From: Tony Lindgren <tony@atomide.com> To: linux-omap@vger.kernel.org Cc: Dave Gerlach <d-gerlach@ti.com>, Faiz Abbas <faiz_abbas@ti.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Keerthy <j-keerthy@ti.com>, Nishanth Menon <nm@ti.com>, Peter Ujfalusi <peter.ujfalusi@ti.com>, Roger Quadros <rogerq@ti.com>, Suman Anna <s-anna@ti.com>, Tero Kristo <t-kristo@ti.com>, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 11/14] bus: ti-sysc: Add quirk handling for external optional functional clock Date: Mon, 25 Mar 2019 14:58:46 -0700 [thread overview] Message-ID: <20190325215849.13182-12-tony@atomide.com> (raw) In-Reply-To: <20190325215849.13182-1-tony@atomide.com> We cannot access mcpdm registers at all unless there is an optional pdmclk configured. As this is currently only needed for mcpdm, let's check for mcpdm in sysc_get_clocks(). If it turns out to be needed for other modules too, we can add more flags to the quirks table for this. Signed-off-by: Tony Lindgren <tony@atomide.com> --- drivers/bus/ti-sysc.c | 90 ++++++++++++++++++++++++++- include/linux/platform_data/ti-sysc.h | 1 + 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -47,7 +47,10 @@ enum sysc_clocks { SYSC_MAX_CLOCKS, }; -static const char * const clock_names[SYSC_ICK + 1] = { "fck", "ick", }; +static const char * const clock_names[SYSC_MAX_CLOCKS] = { + "fck", "ick", "opt0", "opt1", "opt2", "opt3", "opt4", + "opt5", "opt6", "opt7", +}; #define SYSC_IDLEMODE_MASK 3 #define SYSC_CLOCKACTIVITY_MASK 3 @@ -129,6 +132,81 @@ static u32 sysc_read_revision(struct sysc *ddata) return sysc_read(ddata, offset); } +static int sysc_add_named_clock_from_child(struct sysc *ddata, + const char *name, + const char *optfck_name) +{ + struct device_node *np = ddata->dev->of_node; + struct device_node *child; + struct clk_lookup *cl; + struct clk *clock; + const char *n; + + if (name) + n = name; + else + n = optfck_name; + + /* Does the clock alias already exist? */ + clock = of_clk_get_by_name(np, n); + if (!IS_ERR(clock)) { + clk_put(clock); + + return 0; + } + + child = of_get_next_available_child(np, NULL); + if (!child) + return -ENODEV; + + clock = devm_get_clk_from_child(ddata->dev, child, name); + if (IS_ERR(clock)) + return PTR_ERR(clock); + + /* + * Use clkdev_add() instead of clkdev_alloc() to avoid the MAX_DEV_ID + * limit for clk_get(). If cl ever needs to be freed, it should be done + * with clkdev_drop(). + */ + cl = kcalloc(1, sizeof(*cl), GFP_KERNEL); + if (!cl) + return -ENOMEM; + + cl->con_id = n; + cl->dev_id = dev_name(ddata->dev); + cl->clk = clock; + clkdev_add(cl); + + clk_put(clock); + + return 0; +} + +static int sysc_init_ext_opt_clock(struct sysc *ddata, const char *name) +{ + const char *optfck_name; + int error, index; + + if (ddata->nr_clocks < SYSC_OPTFCK0) + index = SYSC_OPTFCK0; + else + index = ddata->nr_clocks; + + if (name) + optfck_name = name; + else + optfck_name = clock_names[index]; + + error = sysc_add_named_clock_from_child(ddata, name, optfck_name); + if (error) + return error; + + ddata->clock_roles[index] = optfck_name; + ddata->nr_clocks++; + + return 0; +} + static int sysc_get_one_clock(struct sysc *ddata, const char *name) { int error, i, index = -ENODEV; @@ -200,6 +278,12 @@ static int sysc_get_clocks(struct sysc *ddata) if (ddata->nr_clocks < 1) return 0; + if ((ddata->cfg.quirks & SYSC_QUIRK_EXT_OPT_CLOCK)) { + error = sysc_init_ext_opt_clock(ddata, NULL); + if (error) + return error; + } + if (ddata->nr_clocks > SYSC_MAX_CLOCKS) { dev_err(ddata->dev, "too many clocks for %pOF\n", np); @@ -901,6 +985,10 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, SYSC_QUIRK_LEGACY_IDLE), + /* Quirks that need to be set based on the module address */ + SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -1, 0x50000800, 0xffffffff, + SYSC_QUIRK_EXT_OPT_CLOCK), + #ifdef DEBUG SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0), SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0), diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h --- a/include/linux/platform_data/ti-sysc.h +++ b/include/linux/platform_data/ti-sysc.h @@ -46,6 +46,7 @@ struct sysc_regbits { s8 emufree_shift; }; +#define SYSC_QUIRK_EXT_OPT_CLOCK BIT(10) #define SYSC_QUIRK_LEGACY_IDLE BIT(9) #define SYSC_QUIRK_RESET_STATUS BIT(8) #define SYSC_QUIRK_NO_IDLE BIT(7) -- 2.21.0
WARNING: multiple messages have this Message-ID (diff)
From: Tony Lindgren <tony@atomide.com> To: linux-omap@vger.kernel.org Cc: Nishanth Menon <nm@ti.com>, Tero Kristo <t-kristo@ti.com>, Dave Gerlach <d-gerlach@ti.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, linux-kernel@vger.kernel.org, Peter Ujfalusi <peter.ujfalusi@ti.com>, Faiz Abbas <faiz_abbas@ti.com>, Keerthy <j-keerthy@ti.com>, linux-arm-kernel@lists.infradead.org, Roger Quadros <rogerq@ti.com> Subject: [PATCH 11/14] bus: ti-sysc: Add quirk handling for external optional functional clock Date: Mon, 25 Mar 2019 14:58:46 -0700 [thread overview] Message-ID: <20190325215849.13182-12-tony@atomide.com> (raw) In-Reply-To: <20190325215849.13182-1-tony@atomide.com> We cannot access mcpdm registers at all unless there is an optional pdmclk configured. As this is currently only needed for mcpdm, let's check for mcpdm in sysc_get_clocks(). If it turns out to be needed for other modules too, we can add more flags to the quirks table for this. Signed-off-by: Tony Lindgren <tony@atomide.com> --- drivers/bus/ti-sysc.c | 90 ++++++++++++++++++++++++++- include/linux/platform_data/ti-sysc.h | 1 + 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -47,7 +47,10 @@ enum sysc_clocks { SYSC_MAX_CLOCKS, }; -static const char * const clock_names[SYSC_ICK + 1] = { "fck", "ick", }; +static const char * const clock_names[SYSC_MAX_CLOCKS] = { + "fck", "ick", "opt0", "opt1", "opt2", "opt3", "opt4", + "opt5", "opt6", "opt7", +}; #define SYSC_IDLEMODE_MASK 3 #define SYSC_CLOCKACTIVITY_MASK 3 @@ -129,6 +132,81 @@ static u32 sysc_read_revision(struct sysc *ddata) return sysc_read(ddata, offset); } +static int sysc_add_named_clock_from_child(struct sysc *ddata, + const char *name, + const char *optfck_name) +{ + struct device_node *np = ddata->dev->of_node; + struct device_node *child; + struct clk_lookup *cl; + struct clk *clock; + const char *n; + + if (name) + n = name; + else + n = optfck_name; + + /* Does the clock alias already exist? */ + clock = of_clk_get_by_name(np, n); + if (!IS_ERR(clock)) { + clk_put(clock); + + return 0; + } + + child = of_get_next_available_child(np, NULL); + if (!child) + return -ENODEV; + + clock = devm_get_clk_from_child(ddata->dev, child, name); + if (IS_ERR(clock)) + return PTR_ERR(clock); + + /* + * Use clkdev_add() instead of clkdev_alloc() to avoid the MAX_DEV_ID + * limit for clk_get(). If cl ever needs to be freed, it should be done + * with clkdev_drop(). + */ + cl = kcalloc(1, sizeof(*cl), GFP_KERNEL); + if (!cl) + return -ENOMEM; + + cl->con_id = n; + cl->dev_id = dev_name(ddata->dev); + cl->clk = clock; + clkdev_add(cl); + + clk_put(clock); + + return 0; +} + +static int sysc_init_ext_opt_clock(struct sysc *ddata, const char *name) +{ + const char *optfck_name; + int error, index; + + if (ddata->nr_clocks < SYSC_OPTFCK0) + index = SYSC_OPTFCK0; + else + index = ddata->nr_clocks; + + if (name) + optfck_name = name; + else + optfck_name = clock_names[index]; + + error = sysc_add_named_clock_from_child(ddata, name, optfck_name); + if (error) + return error; + + ddata->clock_roles[index] = optfck_name; + ddata->nr_clocks++; + + return 0; +} + static int sysc_get_one_clock(struct sysc *ddata, const char *name) { int error, i, index = -ENODEV; @@ -200,6 +278,12 @@ static int sysc_get_clocks(struct sysc *ddata) if (ddata->nr_clocks < 1) return 0; + if ((ddata->cfg.quirks & SYSC_QUIRK_EXT_OPT_CLOCK)) { + error = sysc_init_ext_opt_clock(ddata, NULL); + if (error) + return error; + } + if (ddata->nr_clocks > SYSC_MAX_CLOCKS) { dev_err(ddata->dev, "too many clocks for %pOF\n", np); @@ -901,6 +985,10 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, SYSC_QUIRK_LEGACY_IDLE), + /* Quirks that need to be set based on the module address */ + SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -1, 0x50000800, 0xffffffff, + SYSC_QUIRK_EXT_OPT_CLOCK), + #ifdef DEBUG SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0), SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0), diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h --- a/include/linux/platform_data/ti-sysc.h +++ b/include/linux/platform_data/ti-sysc.h @@ -46,6 +46,7 @@ struct sysc_regbits { s8 emufree_shift; }; +#define SYSC_QUIRK_EXT_OPT_CLOCK BIT(10) #define SYSC_QUIRK_LEGACY_IDLE BIT(9) #define SYSC_QUIRK_RESET_STATUS BIT(8) #define SYSC_QUIRK_NO_IDLE BIT(7) -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-03-25 21:59 UTC|newest] Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-03-25 21:58 [PATCH 00/14] ti-sysc changes to probe devices with dts data only Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 01/14] bus: ti-sysc: Fix sysc_unprepare() when no clocks have been allocated Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 02/14] bus: ti-sysc: Handle missed no-idle property in addition to no-idle-on-init Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-31 6:41 ` Rob Herring 2019-03-31 6:41 ` Rob Herring 2019-03-31 6:41 ` Rob Herring 2019-03-25 21:58 ` [PATCH 03/14] bus: ti-sysc: Make functions static Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 04/14] bus: ti-sysc: Move legacy platform data idling into separate functions Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 05/14] bus: ti-sysc: Add separate functions for handling clocks Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-04-03 18:00 ` Tony Lindgren 2019-04-03 18:00 ` Tony Lindgren 2019-04-03 18:00 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 06/14] bus: ti-sysc: Enable all clocks directly during init to read revision Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 07/14] bus: ti-sysc: Allocate mdata as needed and do platform data based init later Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 08/14] bus: ti-sysc: Manage clocks for the interconnect target module in all cases Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 09/14] bus: ti-sysc: Move rstctrl reset to happen later Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-26 23:13 ` Tony Lindgren 2019-03-26 23:13 ` Tony Lindgren 2019-03-26 23:13 ` Tony Lindgren 2019-03-26 23:22 ` Suman Anna 2019-03-26 23:22 ` Suman Anna 2019-03-26 23:22 ` Suman Anna 2019-03-26 23:40 ` Tony Lindgren 2019-03-26 23:40 ` Tony Lindgren 2019-03-27 16:27 ` Suman Anna 2019-03-27 16:27 ` Suman Anna 2019-03-27 16:27 ` Suman Anna 2019-03-27 18:37 ` Tony Lindgren 2019-03-27 18:37 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 10/14] bus: ti-sysc: Add support for early quirks based on register address Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren [this message] 2019-03-25 21:58 ` [PATCH 11/14] bus: ti-sysc: Add quirk handling for external optional functional clock Tony Lindgren 2019-04-08 16:51 ` Tony Lindgren 2019-04-08 16:51 ` Tony Lindgren 2019-04-08 16:51 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 12/14] bus: ti-sysc: Pass clockactivity quirk to platform functions Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 13/14] bus: ti-sysc: Handle swsup idle mode quirks Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren 2019-03-25 21:58 ` [PATCH 14/14] bus: ti-sysc: Detect DMIC for debugging Tony Lindgren 2019-03-25 21:58 ` Tony Lindgren
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20190325215849.13182-12-tony@atomide.com \ --to=tony@atomide.com \ --cc=d-gerlach@ti.com \ --cc=faiz_abbas@ti.com \ --cc=gregkh@linuxfoundation.org \ --cc=j-keerthy@ti.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-omap@vger.kernel.org \ --cc=nm@ti.com \ --cc=peter.ujfalusi@ti.com \ --cc=rogerq@ti.com \ --cc=s-anna@ti.com \ --cc=t-kristo@ti.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.