From a8a97db984bdc5e89d42e41891543d2daaf314cb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 5 Apr 2012 11:42:09 +0100 Subject: ARM: 7376/1: clkdev: Implement managed clk_get() Allow clk API users to simplify their cleanup paths by providing a managed version of clk_get() and clk_put(). Signed-off-by: Mark Brown Signed-off-by: Russell King --- include/linux/clk.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'include/linux') diff --git a/include/linux/clk.h b/include/linux/clk.h index b0252726df61..70cf722ac3af 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -100,6 +100,26 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb); */ struct clk *clk_get(struct device *dev, const char *id); +/** + * devm_clk_get - lookup and obtain a managed reference to a clock producer. + * @dev: device for clock "consumer" + * @id: clock comsumer 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.) + * + * Drivers must assume that the clock source is not enabled. + * + * devm_clk_get should not be called from within interrupt context. + * + * The clock will automatically be freed when the device is unbound + * from the bus. + */ +struct clk *devm_clk_get(struct device *dev, const char *id); + /** * clk_prepare - prepare a clock source * @clk: clock source @@ -206,6 +226,18 @@ unsigned long clk_get_rate(struct clk *clk); */ void clk_put(struct clk *clk); +/** + * devm_clk_put - "free" a managed clock source + * @dev: device used to acuqire the clock + * @clk: clock source acquired with devm_clk_get() + * + * Note: drivers must ensure that all clk_enable calls made on this + * clock source are balanced by clk_disable calls prior to calling + * this function. + * + * clk_put should not be called from within interrupt context. + */ +void devm_clk_put(struct device *dev, struct clk *clk); /* * The remaining APIs are optional for machine class support. -- cgit v1.2.3 From dd5127010afa560b1cfde7e2cffeadabdd20885d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 24 Apr 2012 15:20:02 +0200 Subject: pinctrl: fix dangling comment This comment was referring to an older PINMUX define, it should be PINCTRL now. Reported-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Dong Aisheng Signed-off-by: Linus Walleij --- include/linux/pinctrl/machine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index e4d1de742502..9c4a19867289 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -163,5 +163,5 @@ static inline int pinctrl_register_mappings(struct pinctrl_map const *map, return 0; } -#endif /* !CONFIG_PINMUX */ +#endif /* !CONFIG_PINCTRL */ #endif -- cgit v1.2.3 From 02ae6da28fb7aa31d8bf1972c99e83c58b684198 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 26 Apr 2012 10:18:52 -0600 Subject: pinctrl: add kerneldoc for pinctrl_ops device tree functions Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij --- include/linux/pinctrl/pinctrl.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index c22d0409d2ef..3b894a668d32 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -72,6 +72,15 @@ struct pinctrl_gpio_range { * group selector @pins, and the size of the array in @num_pins * @pin_dbg_show: optional debugfs display hook that will provide per-device * info for a certain pin in debugfs + * @dt_node_to_map: parse a device tree "pin configuration node", and create + * mapping table entries for it. These are returned through the @map and + * @num_maps output parameters. This function is optional, and may be + * omitted for pinctrl drivers that do not support device tree. + * @dt_free_map: free mapping table entries created via @dt_node_to_map. The + * top-level @map pointer must be freed, along with any dynamically + * allocated members of the mapping table entries themselves. This + * function is optional, and may be omitted for pinctrl drivers that do + * not support device tree. */ struct pinctrl_ops { int (*get_groups_count) (struct pinctrl_dev *pctldev); -- cgit v1.2.3 From 5b3aa5f7c6287b1a0698950a91e94546888e553b Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Thu, 26 Apr 2012 16:15:50 +0800 Subject: pinctrl: add pinctrl_provide_dummies interface for platforms to use Add a interface pinctrl_provide_dummies for platform to indicate whether it needs use pinctrl dummy state. ChangeLog v3->v4: * remove dummy gpio support in pinctrl subsystem. Let gpio driver decide whether it wants to use pinctrl gpio mux function. ChangeLog v2->v3: * Also changed the missed pinctrl gpio APIs in v1. ChangeLog v1->v2: * Based on sascha's suggestion, drop using kconfig since it will hide pinctrl errors on all other boards. See: https://lkml.org/lkml/2012/4/18/282 It seemed both Linus and Stephen agreed with this way, so i'm ok with it too. * Add dummy gpio support. pinctrl gpio in the same situation as state. * Patch name changed. Original is pinctrl: handle dummy state in core. * Split removing old dt dummy interface into a separate patch Cc: Linus Walleij Cc: Sascha Hauer Acked-by: Stephen Warren Signed-off-by: Dong Aisheng Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 29 +++++++++++++++++++++++++++-- include/linux/pinctrl/machine.h | 5 ++++- 2 files changed, 31 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 138e72f74377..a6386b3a3c15 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -43,6 +43,8 @@ struct pinctrl_maps { unsigned num_maps; }; +static bool pinctrl_dummy_state; + /* Mutex taken by all entry points */ DEFINE_MUTEX(pinctrl_mutex); @@ -61,6 +63,19 @@ static LIST_HEAD(pinctrl_maps); _i_ < _maps_node_->num_maps; \ i++, _map_ = &_maps_node_->maps[_i_]) +/** + * pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support + * + * Usually this function is called by platforms without pinctrl driver support + * but run with some shared drivers using pinctrl APIs. + * After calling this function, the pinctrl core will return successfully + * with creating a dummy state for the driver to keep going smoothly. + */ +void pinctrl_provide_dummies(void) +{ + pinctrl_dummy_state = true; +} + const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) { /* We're not allowed to register devices without name */ @@ -719,8 +734,18 @@ static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p, struct pinctrl_state *state; state = find_state(p, name); - if (!state) - return ERR_PTR(-ENODEV); + if (!state) { + if (pinctrl_dummy_state) { + /* create dummy state */ + dev_dbg(p->dev, "using pinctrl dummy state (%s)\n", + name); + state = create_state(p, name); + if (IS_ERR(state)) + return state; + } else { + return ERR_PTR(-ENODEV); + } + } return state; } diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 9c4a19867289..7d22ab00343f 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -154,7 +154,7 @@ struct pinctrl_map { extern int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps); - +extern void pinctrl_provide_dummies(void); #else static inline int pinctrl_register_mappings(struct pinctrl_map const *map, @@ -163,5 +163,8 @@ static inline int pinctrl_register_mappings(struct pinctrl_map const *map, return 0; } +static inline void pinctrl_provide_dummies(void) +{ +} #endif /* !CONFIG_PINCTRL */ #endif -- cgit v1.2.3 From 183f1d0c6450ee032d97a2d01ed5eb00e0dbaa49 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Fri, 27 Apr 2012 11:36:20 +0800 Subject: dt: add of_get_child_count helper function Currently most code to get child count in kernel are almost same, add a helper to implement this function for dt to use. Cc: Grant Likely Acked-by: Rob Herring Acked-by: Stephen Warren Signed-off-by: Dong Aisheng Signed-off-by: Linus Walleij --- include/linux/of.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include/linux') diff --git a/include/linux/of.h b/include/linux/of.h index e3f942d9da89..2ec1083af7ff 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -193,6 +193,17 @@ extern struct device_node *of_get_next_child(const struct device_node *node, for (child = of_get_next_child(parent, NULL); child != NULL; \ child = of_get_next_child(parent, child)) +static inline int of_get_child_count(const struct device_node *np) +{ + struct device_node *child; + int num = 0; + + for_each_child_of_node(np, child) + num++; + + return num; +} + extern struct device_node *of_find_node_with_property( struct device_node *from, const char *prop_name); #define for_each_node_with_property(dn, prop_name) \ @@ -300,6 +311,11 @@ static inline bool of_have_populated_dt(void) #define for_each_child_of_node(parent, child) \ while (0) +static inline int of_get_child_count(const struct device_node *np) +{ + return 0; +} + static inline int of_device_is_compatible(const struct device_node *device, const char *name) { -- cgit v1.2.3 From e9d7f4065408e92338a41b809e437c6e043da090 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 2 May 2012 09:30:32 +0100 Subject: CLKDEV: provide helpers for common clock framework The common clock framework allocates clocks dynamically. Provide a set of helpers to streamline the clkdev registration of the clock lookups to avoid repetitive code sequences. Reviewed-by: Viresh Kumar Tested-by: Shawn Guo Signed-off-by: Russell King --- drivers/clk/clkdev.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++---- include/linux/clkdev.h | 3 ++ 2 files changed, 81 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index d4a59931e75e..c535cf8c5770 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -166,8 +166,9 @@ struct clk_lookup_alloc { char con_id[MAX_CON_ID]; }; -struct clk_lookup * __init_refok -clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...) +static struct clk_lookup * __init_refok +vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, + va_list ap) { struct clk_lookup_alloc *cla; @@ -182,16 +183,25 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...) } if (dev_fmt) { - va_list ap; - - va_start(ap, dev_fmt); vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap); cla->cl.dev_id = cla->dev_id; - va_end(ap); } return &cla->cl; } + +struct clk_lookup * __init_refok +clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...) +{ + struct clk_lookup *cl; + va_list ap; + + va_start(ap, dev_fmt); + cl = vclkdev_alloc(clk, con_id, dev_fmt, ap); + va_end(ap); + + return cl; +} EXPORT_SYMBOL(clkdev_alloc); int clk_add_alias(const char *alias, const char *alias_dev_name, char *id, @@ -223,3 +233,65 @@ void clkdev_drop(struct clk_lookup *cl) kfree(cl); } EXPORT_SYMBOL(clkdev_drop); + +/** + * clk_register_clkdev - register one clock lookup for a struct clk + * @clk: struct clk to associate with all clk_lookups + * @con_id: connection ID string on device + * @dev_id: format string describing device name + * + * con_id or dev_id may be NULL as a wildcard, just as in the rest of + * clkdev. + * + * To make things easier for mass registration, we detect error clks + * from a previous clk_register() call, and return the error code for + * those. This is to permit this function to be called immediately + * after clk_register(). + */ +int clk_register_clkdev(struct clk *clk, const char *con_id, + const char *dev_fmt, ...) +{ + struct clk_lookup *cl; + va_list ap; + + if (IS_ERR(clk)) + return PTR_ERR(clk); + + va_start(ap, dev_fmt); + cl = vclkdev_alloc(clk, con_id, dev_fmt, ap); + va_end(ap); + + if (!cl) + return -ENOMEM; + + clkdev_add(cl); + + return 0; +} + +/** + * clk_register_clkdevs - register a set of clk_lookup for a struct clk + * @clk: struct clk to associate with all clk_lookups + * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized + * @num: number of clk_lookup structures to register + * + * To make things easier for mass registration, we detect error clks + * from a previous clk_register() call, and return the error code for + * those. This is to permit this function to be called immediately + * after clk_register(). + */ +int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num) +{ + unsigned i; + + if (IS_ERR(clk)) + return PTR_ERR(clk); + + for (i = 0; i < num; i++, cl++) { + cl->clk = clk; + clkdev_add(cl); + } + + return 0; +} +EXPORT_SYMBOL(clk_register_clkdevs); diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h index d9a4fd028c9d..a6a6f603103b 100644 --- a/include/linux/clkdev.h +++ b/include/linux/clkdev.h @@ -40,4 +40,7 @@ void clkdev_drop(struct clk_lookup *cl); void clkdev_add_table(struct clk_lookup *, size_t); int clk_add_alias(const char *, const char *, char *, struct device *); +int clk_register_clkdev(struct clk *, const char *, const char *, ...); +int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); + #endif -- cgit v1.2.3 From c7eea50b980b28f4edaa0cfbdf2456532472bc03 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 9 May 2012 09:22:40 +0200 Subject: pinctrl: (cosmetic) fix two entries in DocBook comments This removes a repeated word and a repeated and incomplete line from two pinctrl headers. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Linus Walleij --- include/linux/pinctrl/pinconf.h | 1 - include/linux/pinctrl/pinmux.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h index 7b9d5f00ed37..e7a720104a47 100644 --- a/include/linux/pinctrl/pinconf.h +++ b/include/linux/pinctrl/pinconf.h @@ -25,7 +25,6 @@ struct seq_file; * @pin_config_get: get the config of a certain pin, if the requested config * is not available on this controller this should return -ENOTSUPP * and if it is available but disabled it should return -EINVAL - * @pin_config_get: get the config of a certain pin * @pin_config_set: configure an individual pin * @pin_config_group_get: get configurations for an entire pin group * @pin_config_group_set: configure all pins in a group diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h index dd7bef61d066..1818dcbdd9ab 100644 --- a/include/linux/pinctrl/pinmux.h +++ b/include/linux/pinctrl/pinmux.h @@ -23,7 +23,7 @@ struct pinctrl_dev; /** * struct pinmux_ops - pinmux operations, to be implemented by pin controller * drivers that support pinmuxing - * @request: called by the core to see if a certain pin can be made available + * @request: called by the core to see if a certain pin can be made * available for muxing. This is called by the core to acquire the pins * before selecting any actual mux setting across a function. The driver * is allowed to answer "no" by returning a negative error code -- cgit v1.2.3