From 345b19bca4b1c336f61f17b9aa6a180d934b299f Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Thu, 15 Sep 2016 10:32:03 +0200 Subject: mfd: axp20x: Provide interface for add-on drivers Add-on drivers (e.g. hwmon) utilising a AXP20x, AXP22x or AXP80x need access to the regmap provided by the device, but no interface for retrieving the device/interface exists. This adds a new function axp20x_node_to_regmap(), modelled after the similar syscon_node_to_regmap(), to gain access to the regmap for a AXP-node with a fully loaded driver. Signed-off-by: Philipp Tomsich --- drivers/mfd/axp20x.c | 29 ++++++++++++++++++++++++++++- include/linux/mfd/axp20x.h | 13 +++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 96102753847f..b8324f5dc078 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -28,9 +28,11 @@ #include #include #include - #define AXP20X_OFF 0x80 +static DEFINE_SPINLOCK(axp20x_list_slock); +static LIST_HEAD(axp20x_list); + static const char * const axp20x_model_names[] = { "AXP152", "AXP202", @@ -821,6 +823,27 @@ int axp20x_match_device(struct axp20x_dev *axp20x) } EXPORT_SYMBOL(axp20x_match_device); +struct regmap *axp20x_node_to_regmap(struct device_node *np) +{ + struct axp20x_dev *entry, *axp20x = NULL; + + spin_lock(&axp20x_list_slock); + + list_for_each_entry(entry, &axp20x_list, list) + if (entry->dev && entry->dev->of_node == np) { + axp20x = entry; + break; + } + + spin_unlock(&axp20x_list_slock); + + if (axp20x) + return axp20x->regmap; + + return NULL; +} +EXPORT_SYMBOL_GPL(syscon_node_to_regmap); + int axp20x_device_probe(struct axp20x_dev *axp20x) { int ret; @@ -848,6 +871,10 @@ int axp20x_device_probe(struct axp20x_dev *axp20x) pm_power_off = axp20x_power_off; } + spin_lock(&axp20x_list_slock); + list_add_tail(&axp20x->list, &axp20x_list); + spin_unlock(&axp20x_list_slock); + dev_info(axp20x->dev, "AXP20X driver loaded\n"); return 0; diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h index fec597fb34cb..2ecf8c0b13d1 100644 --- a/include/linux/mfd/axp20x.h +++ b/include/linux/mfd/axp20x.h @@ -11,6 +11,7 @@ #ifndef __LINUX_MFD_AXP20X_H #define __LINUX_MFD_AXP20X_H +#include #include enum { @@ -524,6 +525,7 @@ struct axp20x_dev { struct mfd_cell *cells; const struct regmap_config *regmap_cfg; const struct regmap_irq_chip *regmap_irq_chip; + struct list_head list; }; #define BATTID_LEN 64 @@ -593,6 +595,17 @@ static inline int axp20x_read_variable_width(struct regmap *regmap, */ int axp20x_match_device(struct axp20x_dev *axp20x); +/** + * axp20x_node_to_regmap(): Find the regmap for a axp20x device + * + * @np: node-pointer to the axp20x device + * + * This function lets add-on drivers (e.g. axp809-thermal) retrieve + * a registered axp20x device's regmap. The device must be fully + * configured or NULL will be returned. + */ +struct regmap *axp20x_node_to_regmap(struct device_node *np); + /** * axp20x_device_probe(): Probe a configured axp20x device * -- cgit v1.2.3