diff mbox series

[V4,08/11] clk: imx: scu: add scu clock gpr mux

Message ID 1539504194-28289-9-git-send-email-aisheng.dong@nxp.com (mailing list archive)
State Changes Requested, archived
Headers show
Series clk: imx: add imx8qxp clock support | expand

Commit Message

Dong Aisheng Oct. 14, 2018, 8:08 a.m. UTC
Add scu based clock gpr mux. Unlike the normal scu mux, such
muxes are controlled by GPR bits through SCU sc_misc_set_control
API.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v3->v4:
 * scu headfile path update
v2->v3:
 * structure name and api usage update
v1->v2:
 * no changes except headfile name updated
---
 drivers/clk/imx/scu/Makefile          |  3 +-
 drivers/clk/imx/scu/clk-mux-gpr-scu.c | 90 +++++++++++++++++++++++++++++++++++
 drivers/clk/imx/scu/clk-scu.h         | 11 +++++
 3 files changed, 103 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/scu/clk-mux-gpr-scu.c

Comments

Stephen Boyd Oct. 16, 2018, 9:30 p.m. UTC | #1
Quoting A.s. Dong (2018-10-14 01:08:06)
> diff --git a/drivers/clk/imx/scu/clk-mux-gpr-scu.c b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
> new file mode 100644
> index 0000000..2ad7a80
> --- /dev/null
> +++ b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
> @@ -0,0 +1,90 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2016 Freescale Semiconductor, Inc.
> + * Copyright 2017~2018 NXP
> + *     Dong Aisheng <aisheng.dong@nxp.com>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +
> +#include "clk-scu.h"
> +
> +struct clk_mux_gpr_scu {
> +       struct clk_hw hw;
> +       u32     rsrc_id;
> +       u8      gpr_id;
> +};
> +
> +#define to_clk_mux_gpr_scu(_hw) container_of(_hw, struct clk_mux_gpr_scu, hw)
> +
> +static u8 clk_mux_gpr_scu_get_parent(struct clk_hw *hw)
> +{
> +       struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
> +       u32 val = 0;
> +       int ret;
> +
> +       ret = imx_sc_misc_get_control(ccm_ipc_handle, gpr_mux->rsrc_id,
> +                                     gpr_mux->gpr_id, &val);
> +       if (ret) {
> +               pr_err("%s: failed to get clock parent %d\n",
> +                       clk_hw_get_name(hw), ret);
> +               return 0;
> +       }
> +
> +       return (u8)val;

Nitpick: Please drop explicit casts.

> +}
> +
> +static int clk_mux_gpr_scu_set_parent(struct clk_hw *hw, u8 index)
> +{
> +       struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
> +       int ret;
> +
> +       ret = imx_sc_misc_set_control(ccm_ipc_handle, gpr_mux->rsrc_id,
> +                                     gpr_mux->gpr_id, index);
> +       if (ret)
> +               pr_err("%s: failed to set clock parent %d\n",
> +                       clk_hw_get_name(hw), ret);

Nitpick: These printks are cluttering the code, any chance they can be
removed and you can rely on callers to care if something failed?

> +
> +       return ret;
> +}
> +
> +static const struct clk_ops clk_mux_gpr_scu_ops = {
> +       .get_parent = clk_mux_gpr_scu_get_parent,
> +       .set_parent = clk_mux_gpr_scu_set_parent,
> +};
> +
> +struct clk_hw *clk_register_mux_gpr_scu(const char *name, const char * const *parents,
Dong Aisheng Oct. 17, 2018, 9:07 a.m. UTC | #2
> -----Original Message-----
> From: Stephen Boyd [mailto:sboyd@kernel.org]
> Sent: Wednesday, October 17, 2018 5:31 AM
> Quoting A.s. Dong (2018-10-14 01:08:06)
> > diff --git a/drivers/clk/imx/scu/clk-mux-gpr-scu.c
> > b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
> > new file mode 100644
> > index 0000000..2ad7a80
> > --- /dev/null
> > +++ b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
> > @@ -0,0 +1,90 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2016 Freescale Semiconductor, Inc.
> > + * Copyright 2017~2018 NXP
> > + *     Dong Aisheng <aisheng.dong@nxp.com>
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/err.h>
> > +#include <linux/io.h>
> > +#include <linux/slab.h>
> > +
> > +#include "clk-scu.h"
> > +
> > +struct clk_mux_gpr_scu {
> > +       struct clk_hw hw;
> > +       u32     rsrc_id;
> > +       u8      gpr_id;
> > +};
> > +
> > +#define to_clk_mux_gpr_scu(_hw) container_of(_hw, struct
> > +clk_mux_gpr_scu, hw)
> > +
> > +static u8 clk_mux_gpr_scu_get_parent(struct clk_hw *hw) {
> > +       struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
> > +       u32 val = 0;
> > +       int ret;
> > +
> > +       ret = imx_sc_misc_get_control(ccm_ipc_handle, gpr_mux->rsrc_id,
> > +                                     gpr_mux->gpr_id, &val);
> > +       if (ret) {
> > +               pr_err("%s: failed to get clock parent %d\n",
> > +                       clk_hw_get_name(hw), ret);
> > +               return 0;
> > +       }
> > +
> > +       return (u8)val;
> 
> Nitpick: Please drop explicit casts.
> 

Compiler does it for us already, right?
Will drop it.

> > +}
> > +
> > +static int clk_mux_gpr_scu_set_parent(struct clk_hw *hw, u8 index) {
> > +       struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
> > +       int ret;
> > +
> > +       ret = imx_sc_misc_set_control(ccm_ipc_handle, gpr_mux->rsrc_id,
> > +                                     gpr_mux->gpr_id, index);
> > +       if (ret)
> > +               pr_err("%s: failed to set clock parent %d\n",
> > +                       clk_hw_get_name(hw), ret);
> 
> Nitpick: These printks are cluttering the code, any chance they can be removed
> and you can rely on callers to care if something failed?
> 

Yes, good suggestion.

Regards
Dong Aisheng

> > +
> > +       return ret;
> > +}
> > +
> > +static const struct clk_ops clk_mux_gpr_scu_ops = {
> > +       .get_parent = clk_mux_gpr_scu_get_parent,
> > +       .set_parent = clk_mux_gpr_scu_set_parent, };
> > +
> > +struct clk_hw *clk_register_mux_gpr_scu(const char *name, const char
> > +* const *parents,
Stephen Boyd Oct. 17, 2018, 3:18 p.m. UTC | #3
Quoting A.s. Dong (2018-10-17 02:07:00)
> > -----Original Message-----
> > From: Stephen Boyd [mailto:sboyd@kernel.org]
> > Sent: Wednesday, October 17, 2018 5:31 AM
> > Quoting A.s. Dong (2018-10-14 01:08:06)
> > > diff --git a/drivers/clk/imx/scu/clk-mux-gpr-scu.c
> > > b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
> > > new file mode 100644
> > > index 0000000..2ad7a80
> > > --- /dev/null
> > > +++ b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
> > > @@ -0,0 +1,90 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * Copyright (C) 2016 Freescale Semiconductor, Inc.
> > > + * Copyright 2017~2018 NXP
> > > + *     Dong Aisheng <aisheng.dong@nxp.com>
> > > + */
> > > +
> > > +#include <linux/clk-provider.h>
> > > +#include <linux/err.h>
> > > +#include <linux/io.h>
> > > +#include <linux/slab.h>
> > > +
> > > +#include "clk-scu.h"
> > > +
> > > +struct clk_mux_gpr_scu {
> > > +       struct clk_hw hw;
> > > +       u32     rsrc_id;
> > > +       u8      gpr_id;
> > > +};
> > > +
> > > +#define to_clk_mux_gpr_scu(_hw) container_of(_hw, struct
> > > +clk_mux_gpr_scu, hw)
> > > +
> > > +static u8 clk_mux_gpr_scu_get_parent(struct clk_hw *hw) {
> > > +       struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
> > > +       u32 val = 0;
> > > +       int ret;
> > > +
> > > +       ret = imx_sc_misc_get_control(ccm_ipc_handle, gpr_mux->rsrc_id,
> > > +                                     gpr_mux->gpr_id, &val);
> > > +       if (ret) {
> > > +               pr_err("%s: failed to get clock parent %d\n",
> > > +                       clk_hw_get_name(hw), ret);
> > > +               return 0;
> > > +       }
> > > +
> > > +       return (u8)val;
> > 
> > Nitpick: Please drop explicit casts.
> > 
> 
> Compiler does it for us already, right?
> Will drop it.

Yes and my brain is a tired compiler :)
diff mbox series

Patch

diff --git a/drivers/clk/imx/scu/Makefile b/drivers/clk/imx/scu/Makefile
index aee56bf..a76ed78 100644
--- a/drivers/clk/imx/scu/Makefile
+++ b/drivers/clk/imx/scu/Makefile
@@ -6,4 +6,5 @@  obj-$(CONFIG_MXC_CLK_SCU) += \
 	clk-divider-gpr-scu.o \
 	clk-gate-scu.o \
 	clk-gate-gpr-scu.o \
-	clk-mux-scu.o
+	clk-mux-scu.o \
+	clk-mux-gpr-scu.o
diff --git a/drivers/clk/imx/scu/clk-mux-gpr-scu.c b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
new file mode 100644
index 0000000..2ad7a80
--- /dev/null
+++ b/drivers/clk/imx/scu/clk-mux-gpr-scu.c
@@ -0,0 +1,90 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *	Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "clk-scu.h"
+
+struct clk_mux_gpr_scu {
+	struct clk_hw hw;
+	u32	rsrc_id;
+	u8	gpr_id;
+};
+
+#define to_clk_mux_gpr_scu(_hw) container_of(_hw, struct clk_mux_gpr_scu, hw)
+
+static u8 clk_mux_gpr_scu_get_parent(struct clk_hw *hw)
+{
+	struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
+	u32 val = 0;
+	int ret;
+
+	ret = imx_sc_misc_get_control(ccm_ipc_handle, gpr_mux->rsrc_id,
+				      gpr_mux->gpr_id, &val);
+	if (ret) {
+		pr_err("%s: failed to get clock parent %d\n",
+			clk_hw_get_name(hw), ret);
+		return 0;
+	}
+
+	return (u8)val;
+}
+
+static int clk_mux_gpr_scu_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw);
+	int ret;
+
+	ret = imx_sc_misc_set_control(ccm_ipc_handle, gpr_mux->rsrc_id,
+				      gpr_mux->gpr_id, index);
+	if (ret)
+		pr_err("%s: failed to set clock parent %d\n",
+			clk_hw_get_name(hw), ret);
+
+	return ret;
+}
+
+static const struct clk_ops clk_mux_gpr_scu_ops = {
+	.get_parent = clk_mux_gpr_scu_get_parent,
+	.set_parent = clk_mux_gpr_scu_set_parent,
+};
+
+struct clk_hw *clk_register_mux_gpr_scu(const char *name, const char * const *parents,
+					int num_parents, unsigned long flags,
+					u32 rsrc_id, u8 gpr_id)
+{
+	struct clk_mux_gpr_scu *mux;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_mux_gpr_scu_ops;
+	init.parent_names = parents;
+	init.num_parents = num_parents;
+	init.flags = flags;
+
+	mux->hw.init = &init;
+	mux->rsrc_id = rsrc_id;
+	mux->gpr_id = gpr_id;
+
+	hw = &mux->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(mux);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/scu/clk-scu.h b/drivers/clk/imx/scu/clk-scu.h
index b2b56d3..8cc58e4 100644
--- a/drivers/clk/imx/scu/clk-scu.h
+++ b/drivers/clk/imx/scu/clk-scu.h
@@ -81,4 +81,15 @@  static inline struct clk_hw *imx_clk_mux_scu(const char *name,
 			clk_type);
 }
 
+struct clk_hw *clk_register_mux_gpr_scu(const char *name, const char * const *parents,
+			int num_parents, unsigned long flags,
+			u32 rsrc_id, u8 gpr_id);
+
+static inline struct clk_hw *imx_clk_mux_gpr_scu(const char *name, const char * const *parents,
+			int num_parents, u32 rsrc_id, u8 gpr_id)
+{
+	return clk_register_mux_gpr_scu(name, parents, num_parents,
+			CLK_SET_RATE_NO_REPARENT, rsrc_id, gpr_id);
+}
+
 #endif