diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/bus/ti-sysc.c | 388 | ||||
-rw-r--r-- | drivers/media/rc/ir-rx51.c | 17 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/davinci_nand.c | 6 | ||||
-rw-r--r-- | drivers/soc/renesas/Kconfig | 13 | ||||
-rw-r--r-- | drivers/soc/renesas/Makefile | 2 | ||||
-rw-r--r-- | drivers/soc/renesas/r8a77470-sysc.c | 29 | ||||
-rw-r--r-- | drivers/soc/renesas/r8a77990-sysc.c | 68 | ||||
-rw-r--r-- | drivers/soc/renesas/r8a77995-sysc.c | 3 | ||||
-rw-r--r-- | drivers/soc/renesas/rcar-rst.c | 2 | ||||
-rw-r--r-- | drivers/soc/renesas/rcar-sysc.c | 6 | ||||
-rw-r--r-- | drivers/soc/renesas/rcar-sysc.h | 2 | ||||
-rw-r--r-- | drivers/soc/renesas/renesas-soc.c | 16 |
12 files changed, 489 insertions, 63 deletions
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 7cd2fd04b212..1cc29629d238 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -19,6 +19,7 @@ #include <linux/platform_device.h> #include <linux/pm_domain.h> #include <linux/pm_runtime.h> +#include <linux/reset.h> #include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/slab.h> @@ -32,10 +33,18 @@ static const char * const reg_names[] = { "rev", "sysc", "syss", }; enum sysc_clocks { SYSC_FCK, SYSC_ICK, + SYSC_OPTFCK0, + SYSC_OPTFCK1, + SYSC_OPTFCK2, + SYSC_OPTFCK3, + SYSC_OPTFCK4, + SYSC_OPTFCK5, + SYSC_OPTFCK6, + SYSC_OPTFCK7, SYSC_MAX_CLOCKS, }; -static const char * const clock_names[] = { "fck", "ick", }; +static const char * const clock_names[SYSC_ICK + 1] = { "fck", "ick", }; #define SYSC_IDLEMODE_MASK 3 #define SYSC_CLOCKACTIVITY_MASK 3 @@ -48,6 +57,8 @@ static const char * const clock_names[] = { "fck", "ick", }; * @module_va: virtual address of the interconnect target module * @offsets: register offsets from module base * @clocks: clocks used by the interconnect target module + * @clock_roles: clock role names for the found clocks + * @nr_clocks: number of clocks used by the interconnect target module * @legacy_mode: configured for legacy mode if set * @cap: interconnect target module capabilities * @cfg: interconnect target module configuration @@ -61,7 +72,10 @@ struct sysc { u32 module_size; void __iomem *module_va; int offsets[SYSC_MAX_REGS]; - struct clk *clocks[SYSC_MAX_CLOCKS]; + struct clk **clocks; + const char **clock_roles; + int nr_clocks; + struct reset_control *rsts; const char *legacy_mode; const struct sysc_capabilities *cap; struct sysc_config cfg; @@ -88,6 +102,11 @@ static u32 sysc_read(struct sysc *ddata, int offset) return readl_relaxed(ddata->module_va + offset); } +static bool sysc_opt_clks_needed(struct sysc *ddata) +{ + return !!(ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_NEEDED); +} + static u32 sysc_read_revision(struct sysc *ddata) { int offset = ddata->offsets[SYSC_REVISION]; @@ -98,21 +117,28 @@ static u32 sysc_read_revision(struct sysc *ddata) return sysc_read(ddata, offset); } -static int sysc_get_one_clock(struct sysc *ddata, - enum sysc_clocks index) +static int sysc_get_one_clock(struct sysc *ddata, const char *name) { - const char *name; - int error; + int error, i, index = -ENODEV; + + if (!strncmp(clock_names[SYSC_FCK], name, 3)) + index = SYSC_FCK; + else if (!strncmp(clock_names[SYSC_ICK], name, 3)) + index = SYSC_ICK; + + if (index < 0) { + for (i = SYSC_OPTFCK0; i < SYSC_MAX_CLOCKS; i++) { + if (!ddata->clocks[i]) { + index = i; + break; + } + } + } - switch (index) { - case SYSC_FCK: - break; - case SYSC_ICK: - break; - default: - return -EINVAL; + if (index < 0) { + dev_err(ddata->dev, "clock %s not added\n", name); + return index; } - name = clock_names[index]; ddata->clocks[index] = devm_clk_get(ddata->dev, name); if (IS_ERR(ddata->clocks[index])) { @@ -138,10 +164,50 @@ static int sysc_get_one_clock(struct sysc *ddata, static int sysc_get_clocks(struct sysc *ddata) { - int i, error; + struct device_node *np = ddata->dev->of_node; + struct property *prop; + const char *name; + int nr_fck = 0, nr_ick = 0, i, error = 0; - for (i = 0; i < SYSC_MAX_CLOCKS; i++) { - error = sysc_get_one_clock(ddata, i); + ddata->clock_roles = devm_kzalloc(ddata->dev, + sizeof(*ddata->clock_roles) * + SYSC_MAX_CLOCKS, + GFP_KERNEL); + if (!ddata->clock_roles) + return -ENOMEM; + + of_property_for_each_string(np, "clock-names", prop, name) { + if (!strncmp(clock_names[SYSC_FCK], name, 3)) + nr_fck++; + if (!strncmp(clock_names[SYSC_ICK], name, 3)) + nr_ick++; + ddata->clock_roles[ddata->nr_clocks] = name; + ddata->nr_clocks++; + } + + if (ddata->nr_clocks < 1) + return 0; + + if (ddata->nr_clocks > SYSC_MAX_CLOCKS) { + dev_err(ddata->dev, "too many clocks for %pOF\n", np); + + return -EINVAL; + } + + if (nr_fck > 1 || nr_ick > 1) { + dev_err(ddata->dev, "max one fck and ick for %pOF\n", np); + + return -EINVAL; + } + + ddata->clocks = devm_kzalloc(ddata->dev, + sizeof(*ddata->clocks) * ddata->nr_clocks, + GFP_KERNEL); + if (!ddata->clocks) + return -ENOMEM; + + for (i = 0; i < ddata->nr_clocks; i++) { + error = sysc_get_one_clock(ddata, ddata->clock_roles[i]); if (error && error != -ENOENT) return error; } @@ -150,6 +216,42 @@ static int sysc_get_clocks(struct sysc *ddata) } /** + * sysc_init_resets - reset module on init + * @ddata: device driver data + * + * A module can have both OCP softreset control and external rstctrl. + * If more complicated rstctrl resets are needed, please handle these + * directly from the child device driver and map only the module reset + * for the parent interconnect target module device. + * + * Automatic reset of the module on init can be skipped with the + * "ti,no-reset-on-init" device tree property. + */ +static int sysc_init_resets(struct sysc *ddata) +{ + int error; + + ddata->rsts = + devm_reset_control_array_get_optional_exclusive(ddata->dev); + if (IS_ERR(ddata->rsts)) + return PTR_ERR(ddata->rsts); + + if (ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) + goto deassert; + + error = reset_control_assert(ddata->rsts); + if (error) + return error; + +deassert: + error = reset_control_deassert(ddata->rsts); + if (error) + return error; + + return 0; +} + +/** * sysc_parse_and_check_child_range - parses module IO region from ranges * @ddata: device driver data * @@ -533,9 +635,13 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev) goto idled; } - for (i = 0; i < SYSC_MAX_CLOCKS; i++) { + for (i = 0; i < ddata->nr_clocks; i++) { if (IS_ERR_OR_NULL(ddata->clocks[i])) continue; + + if (i >= SYSC_OPTFCK0 && !sysc_opt_clks_needed(ddata)) + break; + clk_disable(ddata->clocks[i]); } @@ -572,9 +678,13 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev) goto awake; } - for (i = 0; i < SYSC_MAX_CLOCKS; i++) { + for (i = 0; i < ddata->nr_clocks; i++) { if (IS_ERR_OR_NULL(ddata->clocks[i])) continue; + + if (i >= SYSC_OPTFCK0 && !sysc_opt_clks_needed(ddata)) + break; + error = clk_enable(ddata->clocks[i]); if (error) return error; @@ -590,23 +700,103 @@ awake: static int sysc_suspend(struct device *dev) { struct sysc *ddata; + int error; ddata = dev_get_drvdata(dev); + if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER | + SYSC_QUIRK_LEGACY_IDLE)) + return 0; + if (!ddata->enabled) return 0; + dev_dbg(ddata->dev, "%s %s\n", __func__, + ddata->name ? ddata->name : ""); + + error = pm_runtime_put_sync_suspend(dev); + if (error < 0) { + dev_warn(ddata->dev, "%s not idle %i %s\n", + __func__, error, + ddata->name ? ddata->name : ""); + + return 0; + } + ddata->needs_resume = true; - return sysc_runtime_suspend(dev); + return 0; } static int sysc_resume(struct device *dev) { struct sysc *ddata; + int error; + + ddata = dev_get_drvdata(dev); + + if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER | + SYSC_QUIRK_LEGACY_IDLE)) + return 0; + + if (ddata->needs_resume) { + dev_dbg(ddata->dev, "%s %s\n", __func__, + ddata->name ? ddata->name : ""); + + error = pm_runtime_get_sync(dev); + if (error < 0) { + dev_err(ddata->dev, "%s error %i %s\n", + __func__, error, + ddata->name ? ddata->name : ""); + + return error; + } + + ddata->needs_resume = false; + } + + return 0; +} + +static int sysc_noirq_suspend(struct device *dev) +{ + struct sysc *ddata; ddata = dev_get_drvdata(dev); + + if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE) + return 0; + + if (!(ddata->cfg.quirks & SYSC_QUIRK_RESOURCE_PROVIDER)) + return 0; + + if (!ddata->enabled) + return 0; + + dev_dbg(ddata->dev, "%s %s\n", __func__, + ddata->name ? ddata->name : ""); + + ddata->needs_resume = true; + + return sysc_runtime_suspend(dev); +} + +static int sysc_noirq_resume(struct device *dev) +{ + struct sysc *ddata; + + ddata = dev_get_drvdata(dev); + + if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE) + return 0; + + if (!(ddata->cfg.quirks & SYSC_QUIRK_RESOURCE_PROVIDER)) + return 0; + if (ddata->needs_resume) { + dev_dbg(ddata->dev, "%s %s\n", __func__, + ddata->name ? ddata->name : ""); + ddata->needs_resume = false; return sysc_runtime_resume(dev); @@ -618,6 +808,7 @@ static int sysc_resume(struct device *dev) static const struct dev_pm_ops sysc_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(sysc_suspend, sysc_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sysc_noirq_suspend, sysc_noirq_resume) SET_RUNTIME_PM_OPS(sysc_runtime_suspend, sysc_runtime_resume, NULL) @@ -649,9 +840,29 @@ struct sysc_revision_quirk { } static const struct sysc_revision_quirk sysc_revision_quirks[] = { + /* These need to use noirq_suspend */ + SYSC_QUIRK("control", 0, 0, 0x10, -1, 0x40000900, 0xffffffff, + SYSC_QUIRK_RESOURCE_PROVIDER), + SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xffffffff, + SYSC_QUIRK_RESOURCE_PROVIDER), + SYSC_QUIRK("mcspi", 0, 0, 0x10, -1, 0x40300a0b, 0xffffffff, + SYSC_QUIRK_RESOURCE_PROVIDER), + SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff, + SYSC_QUIRK_RESOURCE_PROVIDER), + SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xffffffff, + SYSC_QUIRK_RESOURCE_PROVIDER), + SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff, + SYSC_QUIRK_RESOURCE_PROVIDER), + SYSC_QUIRK("scm", 0, 0, 0x10, -1, 0x40000900, 0xffffffff, + SYSC_QUIRK_RESOURCE_PROVIDER), + SYSC_QUIRK("scrm", 0, 0, -1, -1, 0x00000010, 0xffffffff, + SYSC_QUIRK_RESOURCE_PROVIDER), + SYSC_QUIRK("sdma", 0, 0, 0x2c, 0x28, 0x00010900, 0xffffffff, + SYSC_QUIRK_RESOURCE_PROVIDER), + /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffffffff, - SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_OPT_CLKS_IN_RESET), SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000020, 0xffffffff, SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000030, 0xffffffff, @@ -664,8 +875,40 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff, SYSC_QUIRK_LEGACY_IDLE), + /* Some timers on omap4 and later */ + SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, SYSC_QUIRK_LEGACY_IDLE), + /* Uarts on omap4 and later */ + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + + /* These devices don't yet suspend properly without legacy setting */ + SYSC_QUIRK("sdio", 0, 0, 0x10, -1, 0x40202301, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0d00, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + +#ifdef DEBUG + SYSC_QUIRK("aess", 0, 0, 0x10, -1, 0x40000000, 0xffffffff, 0), + SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0), + SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, 0), + SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0), + SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0), + SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44306302, 0xffffffff, 0), + SYSC_QUIRK("mcbsp", 0, -1, 0x8c, -1, 0, 0, 0), + SYSC_QUIRK("mailbox", 0, 0, 0x10, -1, 0x00000400, 0xffffffff, 0), + SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40000902, 0xffffffff, 0), + SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40002903, 0xffffffff, 0), + SYSC_QUIRK("spinlock", 0, 0, 0x10, -1, 0x50020000, 0xffffffff, 0), + SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000004, 0xffffffff, 0), + SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, 0), + SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050, + 0xffffffff, 0), +#endif }; static void sysc_init_revision_quirks(struct sysc *ddata) @@ -716,6 +959,7 @@ static int sysc_init_module(struct sysc *ddata) return 0; } + ddata->revision = sysc_read_revision(ddata); pm_runtime_put_sync(ddata->dev); @@ -811,29 +1055,58 @@ static int sysc_init_syss_mask(struct sysc *ddata) } /* - * Many child device drivers need to have fck available to get the clock - * rate for device internal configuration. + * Many child device drivers need to have fck and opt clocks available + * to get the clock rate for device internal configuration etc. */ -static int sysc_child_add_fck(struct sysc *ddata, - struct device *child) +static int sysc_child_add_named_clock(struct sysc *ddata, + struct device *child, + const char *name) { - struct clk *fck; + struct clk *clk; struct clk_lookup *l; - const char *name = clock_names[SYSC_FCK]; + int error = 0; - if (IS_ERR_OR_NULL(ddata->clocks[SYSC_FCK])) + if (!name) return 0; - fck = clk_get(child, name); - if (!IS_ERR(fck)) { - clk_put(fck); + clk = clk_get(child, name); + if (!IS_ERR(clk)) { + clk_put(clk); return -EEXIST; } - l = clkdev_create(ddata->clocks[SYSC_FCK], name, dev_name(child)); + clk = clk_get(ddata->dev, name); + if (IS_ERR(clk)) + return -ENODEV; + + l = clkdev_create(clk, name, dev_name(child)); + if (!l) + error = -ENOMEM; + + clk_put(clk); + + return error; +} + +static int sysc_child_add_clocks(struct sysc *ddata, + struct device *child) +{ + int i, error; + + for (i = 0; i < ddata->nr_clocks; i++) { + error = sysc_child_add_named_clock(ddata, + child, + ddata->clock_roles[i]); + if (error && error != -EEXIST) { + dev_err(ddata->dev, "could not add child clock %s: %i\n", + ddata->clock_roles[i], error); + + return error; + } + } - return l ? 0 : -ENODEV; + return 0; } static struct device_type sysc_device_type = { @@ -891,18 +1164,33 @@ static int sysc_child_suspend_noirq(struct device *dev) ddata = sysc_child_to_parent(dev); + dev_dbg(ddata->dev, "%s %s\n", __func__, + ddata->name ? ddata->name : ""); + error = pm_generic_suspend_noirq(dev); - if (error) + if (error) { + dev_err(dev, "%s error at %i: %i\n", + __func__, __LINE__, error); + return error; + } if (!pm_runtime_status_suspended(dev)) { error = pm_generic_runtime_suspend(dev); - if (error) + if (error) { + dev_err(dev, "%s error at %i: %i\n", + __func__, __LINE__, error); + return error; + } error = sysc_runtime_suspend(ddata->dev); - if (error) + if (error) { + dev_err(dev, "%s error at %i: %i\n", + __func__, __LINE__, error); + return error; + } ddata->child_needs_resume = true; } @@ -917,6 +1205,9 @@ static int sysc_child_resume_noirq(struct device *dev) ddata = sysc_child_to_parent(dev); + dev_dbg(ddata->dev, "%s %s\n", __func__, + ddata->name ? ddata->name : ""); + if (ddata->child_needs_resume) { ddata->child_needs_resume = false; @@ -983,10 +1274,9 @@ static int sysc_notifier_call(struct notifier_block *nb, switch (event) { case BUS_NOTIFY_ADD_DEVICE: - error = sysc_child_add_fck(ddata, dev); - if (error && error != -EEXIST) - dev_warn(ddata->dev, "could not add %s fck: %i\n", - dev_name(dev), error); + error = sysc_child_add_clocks(ddata, dev); + if (error) + return error; sysc_legacy_idle_quirk(ddata, dev); break; default: @@ -1314,6 +1604,11 @@ static void ti_sysc_idle(struct work_struct *work) pm_runtime_put_sync(ddata->dev); } +static const struct of_device_id sysc_match_table[] = { + { .compatible = "simple-bus", }, + { /* sentinel */ }, +}; + static int sysc_probe(struct platform_device *pdev) { struct ti_sysc_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -1359,8 +1654,11 @@ static int sysc_probe(struct platform_device *pdev) if (error) goto unprepare; - pm_runtime_enable(ddata->dev); + error = sysc_init_resets(ddata); + if (error) + return error; + pm_runtime_enable(ddata->dev); error = sysc_init_module(ddata); if (error) goto unprepare; @@ -1375,8 +1673,8 @@ static int sysc_probe(struct platform_device *pdev) sysc_show_registers(ddata); ddata->dev->type = &sysc_device_type; - error = of_platform_populate(ddata->dev->of_node, - NULL, pdata ? pdata->auxdata : NULL, + error = of_platform_populate(ddata->dev->of_node, sysc_match_table, + pdata ? pdata->auxdata : NULL, ddata->dev); if (error) goto err; @@ -1391,6 +1689,9 @@ static int sysc_probe(struct platform_device *pdev) pm_runtime_put(&pdev->dev); } + if (!of_get_available_child_count(ddata->dev->of_node)) + reset_control_assert(ddata->rsts); + return 0; err: @@ -1420,6 +1721,7 @@ static int sysc_remove(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); + reset_control_assert(ddata->rsts); unprepare: sysc_unprepare(ddata); diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c index 49265f02e772..8a93f7468622 100644 --- a/drivers/media/rc/ir-rx51.c +++ b/drivers/media/rc/ir-rx51.c @@ -22,7 +22,6 @@ #include <linux/hrtimer.h> #include <media/rc-core.h> -#include <linux/platform_data/media/ir-rx51.h> #define WBUF_LEN 256 @@ -31,7 +30,6 @@ struct ir_rx51 { struct pwm_device *pwm; struct hrtimer timer; struct device *dev; - struct ir_rx51_platform_data *pdata; wait_queue_head_t wqueue; unsigned int freq; /* carrier frequency */ @@ -130,10 +128,9 @@ static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer, ir_rx51->wbuf[count] = -1; /* Insert termination mark */ /* - * Adjust latency requirements so the device doesn't go in too - * deep sleep states + * REVISIT: Adjust latency requirements so the device doesn't go in too + * deep sleep states with pm_qos_add_request(). */ - ir_rx51->pdata->set_max_mpu_wakeup_lat(ir_rx51->dev, 50); ir_rx51_on(ir_rx51); ir_rx51->wbuf_index = 1; @@ -146,8 +143,7 @@ static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer, */ wait_event_interruptible(ir_rx51->wqueue, ir_rx51->wbuf_index < 0); - /* We can sleep again */ - ir_rx51->pdata->set_max_mpu_wakeup_lat(ir_rx51->dev, -1); + /* REVISIT: Remove pm_qos constraint, we can sleep again */ return count; } @@ -244,13 +240,6 @@ static int ir_rx51_probe(struct platform_device *dev) struct pwm_device *pwm; struct rc_dev *rcdev; - ir_rx51.pdata = dev->dev.platform_data; - - if (!ir_rx51.pdata) { - dev_err(&dev->dev, "Platform Data is missing\n"); - return -ENXIO; - } - pwm = pwm_get(&dev->dev, NULL); if (IS_ERR(pwm)) { int err = PTR_ERR(pwm); diff --git a/drivers/mtd/nand/raw/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c index 7255a0d94374..cd12e5abafde 100644 --- a/drivers/mtd/nand/raw/davinci_nand.c +++ b/drivers/mtd/nand/raw/davinci_nand.c @@ -545,7 +545,7 @@ static struct davinci_nand_pdata return ERR_PTR(-ENOMEM); if (!of_property_read_u32(pdev->dev.of_node, "ti,davinci-chipselect", &prop)) - pdev->id = prop; + pdata->core_chipsel = prop; else return ERR_PTR(-EINVAL); @@ -627,7 +627,7 @@ static int nand_davinci_probe(struct platform_device *pdev) return -ENODEV; /* which external chipselect will we be managing? */ - if (pdev->id < 0 || pdev->id > 3) + if (pdata->core_chipsel < 0 || pdata->core_chipsel > 3) return -ENODEV; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); @@ -683,7 +683,7 @@ static int nand_davinci_probe(struct platform_device *pdev) info->ioaddr = (uint32_t __force) vaddr; info->current_cs = info->ioaddr; - info->core_chipsel = pdev->id; + info->core_chipsel = pdata->core_chipsel; info->mask_chipsel = pdata->mask_chipsel; /* use nandboot-capable ALE/CLE masks by default */ diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 3bbe6114a420..1d824cbd462d 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -4,9 +4,11 @@ config SOC_RENESAS select SOC_BUS select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \ ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \ - ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77995 + ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77990 || \ + ARCH_R8A77995 select SYSC_R8A7743 if ARCH_R8A7743 select SYSC_R8A7745 if ARCH_R8A7745 + select SYSC_R8A77470 if ARCH_R8A77470 select SYSC_R8A7779 if ARCH_R8A7779 select SYSC_R8A7790 if ARCH_R8A7790 select SYSC_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793 @@ -17,6 +19,7 @@ config SOC_RENESAS select SYSC_R8A77965 if ARCH_R8A77965 select SYSC_R8A77970 if ARCH_R8A77970 select SYSC_R8A77980 if ARCH_R8A77980 + select SYSC_R8A77990 if ARCH_R8A77990 select SYSC_R8A77995 if ARCH_R8A77995 if SOC_RENESAS @@ -30,6 +33,10 @@ config SYSC_R8A7745 bool "RZ/G1E System Controller support" if COMPILE_TEST select SYSC_RCAR +config SYSC_R8A77470 + bool "RZ/G1C System Controller support" if COMPILE_TEST + select SYSC_RCAR + config SYSC_R8A7779 bool "R-Car H1 System Controller support" if COMPILE_TEST select SYSC_RCAR @@ -70,6 +77,10 @@ config SYSC_R8A77980 bool "R-Car V3H System Controller support" if COMPILE_TEST select SYSC_RCAR +config SYSC_R8A77990 + bool "R-Car E3 System Controller support" if COMPILE_TEST + select SYSC_RCAR + config SYSC_R8A77995 bool "R-Car D3 System Controller support" if COMPILE_TEST select SYSC_RCAR diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index ccb5ec57a262..7dc0f20d7907 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_SOC_RENESAS) += renesas-soc.o # SoC obj-$(CONFIG_SYSC_R8A7743) += r8a7743-sysc.o obj-$(CONFIG_SYSC_R8A7745) += r8a7745-sysc.o +obj-$(CONFIG_SYSC_R8A77470) += r8a77470-sysc.o obj-$(CONFIG_SYSC_R8A7779) += r8a7779-sysc.o obj-$(CONFIG_SYSC_R8A7790) += r8a7790-sysc.o obj-$(CONFIG_SYSC_R8A7791) += r8a7791-sysc.o @@ -15,6 +16,7 @@ obj-$(CONFIG_SYSC_R8A7796) += r8a7796-sysc.o obj-$(CONFIG_SYSC_R8A77965) += r8a77965-sysc.o obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o +obj-$(CONFIG_SYSC_R8A77990) += r8a77990-sysc.o obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o # Family diff --git a/drivers/soc/renesas/r8a77470-sysc.c b/drivers/soc/renesas/r8a77470-sysc.c new file mode 100644 index 000000000000..cfa015e208ef --- /dev/null +++ b/drivers/soc/renesas/r8a77470-sysc.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas RZ/G1C System Controller + * + * Copyright (C) 2018 Renesas Electronics Corp. + */ + +#include <linux/bug.h> +#include <linux/kernel.h> + +#include <dt-bindings/power/r8a77470-sysc.h> + +#include "rcar-sysc.h" + +static const struct rcar_sysc_area r8a77470_areas[] __initconst = { + { "always-on", 0, 0, R8A77470_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, + { "ca7-scu", 0x100, 0, R8A77470_PD_CA7_SCU, R8A77470_PD_ALWAYS_ON, + PD_SCU }, + { "ca7-cpu0", 0x1c0, 0, R8A77470_PD_CA7_CPU0, R8A77470_PD_CA7_SCU, + PD_CPU_NOCR }, + { "ca7-cpu1", 0x1c0, 1, R8A77470_PD_CA7_CPU1, R8A77470_PD_CA7_SCU, + PD_CPU_NOCR }, + { "sgx", 0xc0, 0, R8A77470_PD_SGX, R8A77470_PD_ALWAYS_ON }, +}; + +const struct rcar_sysc_info r8a77470_sysc_info __initconst = { + .areas = r8a77470_areas, + .num_areas = ARRAY_SIZE(r8a77470_areas), +}; diff --git a/drivers/soc/renesas/r8a77990-sysc.c b/drivers/soc/renesas/r8a77990-sysc.c new file mode 100644 index 000000000000..15579ebc5ed2 --- /dev/null +++ b/drivers/soc/renesas/r8a77990-sysc.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas R-Car E3 System Controller + * + * Copyright (C) 2018 Renesas Electronics Corp. + */ + +#include <linux/bug.h> +#include <linux/kernel.h> +#include <linux/sys_soc.h> + +#include <dt-bindings/power/r8a77990-sysc.h> + +#include "rcar-sysc.h" + +static struct rcar_sysc_area r8a77990_areas[] __initdata = { + { "always-on", 0, 0, R8A77990_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, + { "ca53-scu", 0x140, 0, R8A77990_PD_CA53_SCU, R8A77990_PD_ALWAYS_ON, + PD_SCU }, + { "ca53-cpu0", 0x200, 0, R8A77990_PD_CA53_CPU0, R8A77990_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu1", 0x200, 1, R8A77990_PD_CA53_CPU1, R8A77990_PD_CA53_SCU, + PD_CPU_NOCR }, + { "cr7", 0x240, 0, R8A77990_PD_CR7, R8A77990_PD_ALWAYS_ON }, + { "a3vc", 0x380, 0, R8A77990_PD_A3VC, R8A77990_PD_ALWAYS_ON }, + { "a2vc1", 0x3c0, 1, R8A77990_PD_A2VC1, R8A77990_PD_A3VC }, + { "3dg-a", 0x100, 0, R8A77990_PD_3DG_A, R8A77990_PD_ALWAYS_ON }, + { "3dg-b", 0x100, 1, R8A77990_PD_3DG_B, R8A77990_PD_3DG_A }, +}; + +static void __init rcar_sysc_fix_parent(struct rcar_sysc_area *areas, + unsigned int num_areas, u8 id, + int new_parent) +{ + unsigned int i; + + for (i = 0; i < num_areas; i++) + if (areas[i].isr_bit == id) { + areas[i].parent = new_parent; + return; + } +} + +/* Fixups for R-Car E3 ES1.0 revision */ +static const struct soc_device_attribute r8a77990[] __initconst = { + { .soc_id = "r8a77990", .revision = "ES1.0" }, + { /* sentinel */ } +}; + +static int __init r8a77990_sysc_init(void) +{ + if (soc_device_match(r8a77990)) { + rcar_sysc_fix_parent(r8a77990_areas, + ARRAY_SIZE(r8a77990_areas), + R8A77990_PD_3DG_A, R8A77990_PD_3DG_B); + rcar_sysc_fix_parent(r8a77990_areas, + ARRAY_SIZE(r8a77990_areas), + R8A77990_PD_3DG_B, R8A77990_PD_ALWAYS_ON); + } + + return 0; +} + +const struct rcar_sysc_info r8a77990_sysc_info __initconst = { + .init = r8a77990_sysc_init, + .areas = r8a77990_areas, + .num_areas = ARRAY_SIZE(r8a77990_areas), +}; diff --git a/drivers/soc/renesas/r8a77995-sysc.c b/drivers/soc/renesas/r8a77995-sysc.c index f718429cab02..1b2ef415bbe1 100644 --- a/drivers/soc/renesas/r8a77995-sysc.c +++ b/drivers/soc/renesas/r8a77995-sysc.c @@ -10,13 +10,12 @@ #include <linux/bug.h> #include <linux/kernel.h> -#include <linux/sys_soc.h> #include <dt-bindings/power/r8a77995-sysc.h> #include "rcar-sysc.h" -static struct rcar_sysc_area r8a77995_areas[] __initdata = { +static const struct rcar_sysc_area r8a77995_areas[] __initconst = { { "always-on", 0, 0, R8A77995_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, { "ca53-scu", 0x140, 0, R8A77995_PD_CA53_SCU, R8A77995_PD_ALWAYS_ON, PD_SCU }, diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index 8e9cb7996ab0..d9c1034e70e9 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -44,6 +44,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = { /* RZ/G is handled like R-Car Gen2 */ { .compatible = "renesas,r8a7743-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7745-rst", .data = &rcar_rst_gen2 }, + { .compatible = "renesas,r8a77470-rst", .data = &rcar_rst_gen2 }, /* R-Car Gen1 */ { .compatible = "renesas,r8a7778-reset-wdt", .data = &rcar_rst_gen1 }, { .compatible = "renesas,r8a7779-reset-wdt", .data = &rcar_rst_gen1 }, @@ -59,6 +60,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = { { .compatible = "renesas,r8a77965-rst", .data = &rcar_rst_gen3 }, { .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen3 }, { .compatible = "renesas,r8a77980-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a77990-rst", .data = &rcar_rst_gen3 }, { .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen3 }, { /* sentinel */ } }; diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index faf20e719361..95120acc4d80 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -261,6 +261,9 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = { #ifdef CONFIG_SYSC_R8A7745 { .compatible = "renesas,r8a7745-sysc", .data = &r8a7745_sysc_info }, #endif +#ifdef CONFIG_SYSC_R8A77470 + { .compatible = "renesas,r8a77470-sysc", .data = &r8a77470_sysc_info }, +#endif #ifdef CONFIG_SYSC_R8A7779 { .compatible = "renesas,r8a7779-sysc", .data = &r8a7779_sysc_info }, #endif @@ -293,6 +296,9 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = { #ifdef CONFIG_SYSC_R8A77980 { .compatible = "renesas,r8a77980-sysc", .data = &r8a77980_sysc_info }, #endif +#ifdef CONFIG_SYSC_R8A77990 + { .compatible = "renesas,r8a77990-sysc", .data = &r8a77990_sysc_info }, +#endif #ifdef CONFIG_SYSC_R8A77995 { .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info }, #endif diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h index dcdc9ec8eba7..a22e7cf25e30 100644 --- a/drivers/soc/renesas/rcar-sysc.h +++ b/drivers/soc/renesas/rcar-sysc.h @@ -51,6 +51,7 @@ struct rcar_sysc_info { extern const struct rcar_sysc_info r8a7743_sysc_info; extern const struct rcar_sysc_info r8a7745_sysc_info; +extern const struct rcar_sysc_info r8a77470_sysc_info; extern const struct rcar_sysc_info r8a7779_sysc_info; extern const struct rcar_sysc_info r8a7790_sysc_info; extern const struct rcar_sysc_info r8a7791_sysc_info; @@ -61,6 +62,7 @@ extern const struct rcar_sysc_info r8a7796_sysc_info; extern const struct rcar_sysc_info r8a77965_sysc_info; extern const struct rcar_sysc_info r8a77970_sysc_info; extern const struct rcar_sysc_info r8a77980_sysc_info; +extern const struct rcar_sysc_info r8a77990_sysc_info; extern const struct rcar_sysc_info r8a77995_sysc_info; diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index ea71c413c926..d44d0e687ab8 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c @@ -100,6 +100,11 @@ static const struct renesas_soc soc_rz_g1e __initconst __maybe_unused = { .id = 0x4c, }; +static const struct renesas_soc soc_rz_g1c __initconst __maybe_unused = { + .family = &fam_rzg, + .id = 0x53, +}; + static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = { .family = &fam_rcar_gen1, }; @@ -159,6 +164,11 @@ static const struct renesas_soc soc_rcar_v3h __initconst __maybe_unused = { .id = 0x56, }; +static const struct renesas_soc soc_rcar_e3 __initconst __maybe_unused = { + .family = &fam_rcar_gen3, + .id = 0x57, +}; + static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = { .family = &fam_rcar_gen3, .id = 0x58, @@ -192,6 +202,9 @@ static const struct of_device_id renesas_socs[] __initconst = { #ifdef CONFIG_ARCH_R8A7745 { .compatible = "renesas,r8a7745", .data = &soc_rz_g1e }, #endif +#ifdef CONFIG_ARCH_R8A77470 + { .compatible = "renesas,r8a77470", .data = &soc_rz_g1c }, +#endif #ifdef CONFIG_ARCH_R8A7778 { .compatible = "renesas,r8a7778", .data = &soc_rcar_m1a }, #endif @@ -228,6 +241,9 @@ static const struct of_device_id renesas_socs[] __initconst = { #ifdef CONFIG_ARCH_R8A77980 { .compatible = "renesas,r8a77980", .data = &soc_rcar_v3h }, #endif +#ifdef CONFIG_ARCH_R8A77990 + { .compatible = "renesas,r8a77990", .data = &soc_rcar_e3 }, +#endif #ifdef CONFIG_ARCH_R8A77995 { .compatible = "renesas,r8a77995", .data = &soc_rcar_d3 }, #endif |