diff mbox series

[v2,2/3] clk: Provide new devm_clk_helpers for prepared and enabled clocks

Message ID 20210301110821.1445756-3-uwe@kleine-koenig.org
State Superseded
Headers show
Series clk: provide new devm helpers for prepared and enabled clocks | expand

Commit Message

Uwe Kleine-König March 1, 2021, 11:08 a.m. UTC
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

When a driver keeps a clock prepared (or enabled) during the whole
lifetime of the driver, these helpers allow to simplify the drivers.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 drivers/clk/clk-devres.c | 31 ++++++++++++++
 include/linux/clk.h      | 87 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 117 insertions(+), 1 deletion(-)

Comments

kernel test robot March 1, 2021, 1 p.m. UTC | #1
Hi "Uwe,

I love your patch! Yet something to improve:

[auto build test ERROR on fe07bfda2fb9cdef8a4d4008a409bb02f35f1bd8]

url:    https://github.com/0day-ci/linux/commits/Uwe-Kleine-K-nig/clk-provide-new-devm-helpers-for-prepared-and-enabled-clocks/20210301-191522
base:   fe07bfda2fb9cdef8a4d4008a409bb02f35f1bd8
config: sh-randconfig-r035-20210301 (attached as .config)
compiler: sh4-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/fb9e331a334ed83c22735b4398e56b121ca9dbf5
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Uwe-Kleine-K-nig/clk-provide-new-devm-helpers-for-prepared-and-enabled-clocks/20210301-191522
        git checkout fb9e331a334ed83c22735b4398e56b121ca9dbf5
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=sh 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/clk-devres.c:22:13: warning: no previous prototype for '__devm_clk_get' [-Wmissing-prototypes]
      22 | struct clk *__devm_clk_get(struct device *dev, const char *id,
         |             ^~~~~~~~~~~~~~
   In file included from include/linux/linkage.h:7,
                    from include/linux/kernel.h:7,
                    from include/linux/clk.h:13,
                    from drivers/clk/clk-devres.c:2:
>> include/linux/export.h:67:36: error: redefinition of '__ksymtab_devm_clk_get_prepared'
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/clk/clk-devres.c:83:1: note: in expansion of macro 'EXPORT_SYMBOL'
      83 | EXPORT_SYMBOL(devm_clk_get_prepared);
         | ^~~~~~~~~~~~~
   include/linux/export.h:67:36: note: previous definition of '__ksymtab_devm_clk_get_prepared' was here
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/clk/clk-devres.c:75:1: note: in expansion of macro 'EXPORT_SYMBOL'
      75 | EXPORT_SYMBOL(devm_clk_get_prepared);
         | ^~~~~~~~~~~~~
>> include/linux/export.h:67:36: error: redefinition of '__ksymtab_devm_clk_get_optional_prepared'
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/clk/clk-devres.c:105:1: note: in expansion of macro 'EXPORT_SYMBOL'
     105 | EXPORT_SYMBOL(devm_clk_get_optional_prepared);
         | ^~~~~~~~~~~~~
   include/linux/export.h:67:36: note: previous definition of '__ksymtab_devm_clk_get_optional_prepared' was here
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/clk/clk-devres.c:97:1: note: in expansion of macro 'EXPORT_SYMBOL'
      97 | EXPORT_SYMBOL(devm_clk_get_optional_prepared);
         | ^~~~~~~~~~~~~


vim +/__ksymtab_devm_clk_get_prepared +67 include/linux/export.h

f50169324df4ad Paul Gortmaker    2011-05-23  41  
7290d58095712a Ard Biesheuvel    2018-08-21  42  #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
7290d58095712a Ard Biesheuvel    2018-08-21  43  #include <linux/compiler.h>
7290d58095712a Ard Biesheuvel    2018-08-21  44  /*
7290d58095712a Ard Biesheuvel    2018-08-21  45   * Emit the ksymtab entry as a pair of relative references: this reduces
7290d58095712a Ard Biesheuvel    2018-08-21  46   * the size by half on 64-bit architectures, and eliminates the need for
7290d58095712a Ard Biesheuvel    2018-08-21  47   * absolute relocations that require runtime processing on relocatable
7290d58095712a Ard Biesheuvel    2018-08-21  48   * kernels.
7290d58095712a Ard Biesheuvel    2018-08-21  49   */
7290d58095712a Ard Biesheuvel    2018-08-21  50  #define __KSYMTAB_ENTRY(sym, sec)					\
7290d58095712a Ard Biesheuvel    2018-08-21  51  	__ADDRESSABLE(sym)						\
7290d58095712a Ard Biesheuvel    2018-08-21  52  	asm("	.section \"___ksymtab" sec "+" #sym "\", \"a\"	\n"	\
ed13fc33f76303 Matthias Maennich 2019-09-06  53  	    "	.balign	4					\n"	\
7290d58095712a Ard Biesheuvel    2018-08-21  54  	    "__ksymtab_" #sym ":				\n"	\
7290d58095712a Ard Biesheuvel    2018-08-21  55  	    "	.long	" #sym "- .				\n"	\
7290d58095712a Ard Biesheuvel    2018-08-21  56  	    "	.long	__kstrtab_" #sym "- .			\n"	\
c3a6cf19e695c8 Masahiro Yamada   2019-10-18  57  	    "	.long	__kstrtabns_" #sym "- .			\n"	\
7290d58095712a Ard Biesheuvel    2018-08-21  58  	    "	.previous					\n")
7290d58095712a Ard Biesheuvel    2018-08-21  59  
7290d58095712a Ard Biesheuvel    2018-08-21  60  struct kernel_symbol {
7290d58095712a Ard Biesheuvel    2018-08-21  61  	int value_offset;
7290d58095712a Ard Biesheuvel    2018-08-21  62  	int name_offset;
8651ec01daedad Matthias Maennich 2019-09-06  63  	int namespace_offset;
7290d58095712a Ard Biesheuvel    2018-08-21  64  };
7290d58095712a Ard Biesheuvel    2018-08-21  65  #else
7290d58095712a Ard Biesheuvel    2018-08-21  66  #define __KSYMTAB_ENTRY(sym, sec)					\
7290d58095712a Ard Biesheuvel    2018-08-21 @67  	static const struct kernel_symbol __ksymtab_##sym		\
7290d58095712a Ard Biesheuvel    2018-08-21  68  	__attribute__((section("___ksymtab" sec "+" #sym), used))	\
ed13fc33f76303 Matthias Maennich 2019-09-06  69  	__aligned(sizeof(void *))					\
c3a6cf19e695c8 Masahiro Yamada   2019-10-18  70  	= { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym }
7290d58095712a Ard Biesheuvel    2018-08-21  71  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot March 1, 2021, 1:40 p.m. UTC | #2
Hi "Uwe,

I love your patch! Yet something to improve:

[auto build test ERROR on fe07bfda2fb9cdef8a4d4008a409bb02f35f1bd8]

url:    https://github.com/0day-ci/linux/commits/Uwe-Kleine-K-nig/clk-provide-new-devm-helpers-for-prepared-and-enabled-clocks/20210301-191522
base:   fe07bfda2fb9cdef8a4d4008a409bb02f35f1bd8
config: i386-randconfig-s002-20210301 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-241-geaceeafa-dirty
        # https://github.com/0day-ci/linux/commit/fb9e331a334ed83c22735b4398e56b121ca9dbf5
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Uwe-Kleine-K-nig/clk-provide-new-devm-helpers-for-prepared-and-enabled-clocks/20210301-191522
        git checkout fb9e331a334ed83c22735b4398e56b121ca9dbf5
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/clk-devres.c:22:13: warning: no previous prototype for '__devm_clk_get' [-Wmissing-prototypes]
      22 | struct clk *__devm_clk_get(struct device *dev, const char *id,
         |             ^~~~~~~~~~~~~~
   /tmp/ccuTaeUR.s: Assembler messages:
>> /tmp/ccuTaeUR.s:37: Error: symbol `__kstrtab_devm_clk_get_prepared' is already defined
>> /tmp/ccuTaeUR.s:39: Error: symbol `__kstrtabns_devm_clk_get_prepared' is already defined
   /tmp/ccuTaeUR.s:45: Error: symbol `__ksymtab_devm_clk_get_prepared' is already defined
>> /tmp/ccuTaeUR.s:82: Error: symbol `__kstrtab_devm_clk_get_optional_prepared' is already defined
>> /tmp/ccuTaeUR.s:84: Error: symbol `__kstrtabns_devm_clk_get_optional_prepared' is already defined
   /tmp/ccuTaeUR.s:90: Error: symbol `__ksymtab_devm_clk_get_optional_prepared' is already defined

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 7ba8670deeb6..7d487e49fca4 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -67,12 +67,43 @@  struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_prepared(struct device *dev, const char *id)
+{
+	return __devm_clk_get(dev, id, clk_get, clk_prepare, clk_unprepare);
+
+}
+EXPORT_SYMBOL(devm_clk_get_prepared);
+
+struct clk *devm_clk_get_enabled(struct device *dev, const char *id)
+{
+	return __devm_clk_get(dev, id, clk_get,
+			      clk_prepare_enable, clk_disable_unprepare);
+
+}
+EXPORT_SYMBOL(devm_clk_get_prepared);
+
 struct clk *devm_clk_get_optional(struct device *dev, const char *id)
 {
 	return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
 }
 EXPORT_SYMBOL(devm_clk_get_optional);
 
+struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id)
+{
+	return __devm_clk_get(dev, id, clk_get_optional,
+			      clk_prepare, clk_unprepare);
+
+}
+EXPORT_SYMBOL(devm_clk_get_optional_prepared);
+
+struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
+{
+	return __devm_clk_get(dev, id, clk_get_optional,
+			      clk_prepare_enable, clk_disable_unprepare);
+
+}
+EXPORT_SYMBOL(devm_clk_get_optional_prepared);
+
 struct clk_bulk_devres {
 	struct clk_bulk_data *clks;
 	int num_clks;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 266e8de3cb51..b3c5da388b08 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -449,7 +449,7 @@  int __must_check devm_clk_bulk_get_all(struct device *dev,
  * the clock producer.  (IOW, @id may be identical strings, but
  * clk_get may return different clock producers depending on @dev.)
  *
- * Drivers must assume that the clock source is not enabled.
+ * Drivers must assume that the clock source is neither prepared nor enabled.
  *
  * devm_clk_get should not be called from within interrupt context.
  *
@@ -458,6 +458,47 @@  int __must_check devm_clk_bulk_get_all(struct device *dev,
  */
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
+/**
+ * devm_clk_get_prepared - devm_clk_get() + clk_prepare()
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Returns a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno.  The implementation
+ * uses @dev and @id to determine the clock consumer, and thereby
+ * the clock producer.  (IOW, @id may be identical strings, but
+ * clk_get may return different clock producers depending on @dev.)
+ *
+ * The returned clk (if valid) is prepared. Drivers must however assume that the
+ * clock is not enabled.
+ *
+ * devm_clk_get_prepared should not be called from within interrupt context.
+ *
+ * The clock will automatically be unprepared and freed when the
+ * device is unbound from the bus.
+ */
+struct clk *devm_clk_get_prepared(struct device *dev, const char *id);
+
+/**
+ * devm_clk_get_enabled - devm_clk_get() + clk_prepare_enable()
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Returns a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno.  The implementation
+ * uses @dev and @id to determine the clock consumer, and thereby
+ * the clock producer.  (IOW, @id may be identical strings, but
+ * clk_get may return different clock producers depending on @dev.)
+ *
+ * The returned clk (if valid) is prepared and enabled.
+ *
+ * devm_clk_get_prepared should not be called from within interrupt context.
+ *
+ * The clock will automatically be disabled, unprepared and freed when the
+ * device is unbound from the bus.
+ */
+struct clk *devm_clk_get_enabled(struct device *dev, const char *id);
+
 /**
  * devm_clk_get_optional - lookup and obtain a managed reference to an optional
  *			   clock producer.
@@ -469,6 +510,26 @@  struct clk *devm_clk_get(struct device *dev, const char *id);
  */
 struct clk *devm_clk_get_optional(struct device *dev, const char *id);
 
+/**
+ * devm_clk_get_optional_prepared - devm_clk_get_optional() + clk_prepare()
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as devm_clk_get_prepared() except where there is no clock producer.
+ * In this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id);
+
+/**
+ * devm_clk_get_optional_enabled - devm_clk_get_optional() + clk_prepare_enable()
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as devm_clk_get_enabled() except where there is no clock producer.
+ * In this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id);
+
 /**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *			     clock producer from child node.
@@ -813,12 +874,36 @@  static inline struct clk *devm_clk_get(struct device *dev, const char *id)
 	return NULL;
 }
 
+static inline struct clk *devm_clk_get_prepared(struct device *dev,
+						const char *id)
+{
+	return NULL;
+}
+
+static inline struct clk *devm_clk_get_enabled(struct device *dev,
+					       const char *id)
+{
+	return NULL;
+}
+
 static inline struct clk *devm_clk_get_optional(struct device *dev,
 						const char *id)
 {
 	return NULL;
 }
 
+static inline struct clk *devm_clk_get_optional_prepared(struct device *dev,
+							 const char *id)
+{
+	return NULL;
+}
+
+static inline struct clk *devm_clk_get_optional_enabled(struct device *dev,
+							const char *id)
+{
+	return NULL;
+}
+
 static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
 						 struct clk_bulk_data *clks)
 {