summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/devicetree.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-11-27 10:00:33 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-11-27 10:00:33 -0800
commitdc5fa4656864d3391cdf13512ffa0733ef72fcdc (patch)
treedd4ce7719e83af33966952bee9e9bb6984d502fb /drivers/pinctrl/devicetree.c
parent3d9e3501a064eff90274f1ce927fe71ca1ff4205 (diff)
parentae75b53e08b95cd189879b00f6a47cbdaab1f0eb (diff)
Merge tag 'pinctrl-v5.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control updates from Linus Walleij: "This is the bulk of pin control changes for v5.5. It is pretty much business as usual, the most interesting thing I think is the pin controller for a new Intel chip called Lightning Mountain, which is according to news reports some kind of embedded network processor and what is surprising about it is that Intel have decided to use device tree to describe the system rather than ACPI that they have traditionally favored. Core changes: - Avoid taking direct references to device tree-supplied device names: these may changed at runtime under certain circumstances to kstrdup them. GPIO related: - Work is ongoing to move to passing the irqchip along as a templated struct gpio_irq_chip when adding a standard gpiolib-based irqchip to a GPIO controller, a few patches in this cycle switches a few pin control drivers over to using this method. New hardware support: - Intel Lightning Mountain SoC pin controller and GPIO support, a first Intel platform to use device tree rather than ACPI to configure the system. News reports says that this SoC is a network processor. - Qualcomm MSM8976 and MSM8956 - Qualcomm PMIC GPIO now also supports PM6150 and PM6150L - Qualcomm SPMI MPP and SPMI GPIO for PM8950 and PMI8950 - Rockchip RK3308 - Renesas R8A77961 - Allwinner Meson-A1 Driver improvements: - get_multiple and set_multiple support for the AT91-PIO4 driver. - Convert Qualcomm SSBI GPIO to use the hierarchical IRQ helpers in the GPIOlib irqchip" * tag 'pinctrl-v5.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (93 commits) pinctrl: ingenic: Add OTG VBUS pin for the JZ4770 pinctrl: ingenic: Handle PIN_CONFIG_OUTPUT config pinctrl: Fix Kconfig indentation pinctrl: lewisburg: Update pin list according to v1.1v6 MAINTAINERS: Replace my email by one @kernel.org pinctrl: armada-37xx: Fix irq mask access in armada_37xx_irq_set_type() dt-bindings: pinctrl: intel: Add for new SoC pinctrl: Add pinmux & GPIO controller driver for a new SoC pinctrl: rza1: remove unnecessary static inline function pinctrl: meson: add pinctrl driver support for Meson-A1 SoC pinctrl: meson: add a new callback for SoCs fixup pinctrl: nomadik: db8500: Add mc0_a_2 pin group without direction control dt-bindings: pinctrl: Convert generic pin mux and config properties to schema pinctrl: cherryview: Missed type change to unsigned int pinctrl: intel: Missed type change to unsigned int pinctrl: use devm_platform_ioremap_resource() to simplify code pinctrl: just return if no valid maps dt-bindings: pinctrl: qcom-pmic-mpp: Add support for PM/PMI8950 pinctrl: qcom: spmi-mpp: Add PM/PMI8950 compatible strings dt-bindings: pinctrl: qcom-pmic-gpio: Add support for PM/PMI8950 ...
Diffstat (limited to 'drivers/pinctrl/devicetree.c')
-rw-r--r--drivers/pinctrl/devicetree.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index 5d6d8b1e9062..674920daac26 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -29,6 +29,13 @@ struct pinctrl_dt_map {
static void dt_free_map(struct pinctrl_dev *pctldev,
struct pinctrl_map *map, unsigned num_maps)
{
+ int i;
+
+ for (i = 0; i < num_maps; ++i) {
+ kfree_const(map[i].dev_name);
+ map[i].dev_name = NULL;
+ }
+
if (pctldev) {
const struct pinctrl_ops *ops = pctldev->desc->pctlops;
if (ops->dt_free_map)
@@ -63,7 +70,13 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
/* Initialize common mapping table entry fields */
for (i = 0; i < num_maps; i++) {
- map[i].dev_name = dev_name(p->dev);
+ const char *devname;
+
+ devname = kstrdup_const(dev_name(p->dev), GFP_KERNEL);
+ if (!devname)
+ goto err_free_map;
+
+ map[i].dev_name = devname;
map[i].name = statename;
if (pctldev)
map[i].ctrl_dev_name = dev_name(pctldev->dev);
@@ -71,10 +84,8 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
/* Remember the converted mapping table entries */
dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL);
- if (!dt_map) {
- dt_free_map(pctldev, map, num_maps);
- return -ENOMEM;
- }
+ if (!dt_map)
+ goto err_free_map;
dt_map->pctldev = pctldev;
dt_map->map = map;
@@ -82,6 +93,10 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
list_add_tail(&dt_map->node, &p->dt_maps);
return pinctrl_register_map(map, num_maps, false);
+
+err_free_map:
+ dt_free_map(pctldev, map, num_maps);
+ return -ENOMEM;
}
struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
@@ -147,6 +162,16 @@ static int dt_to_map_one_config(struct pinctrl *p,
ret = ops->dt_node_to_map(pctldev, np_config, &map, &num_maps);
if (ret < 0)
return ret;
+ else if (num_maps == 0) {
+ /*
+ * If we have no valid maps (maybe caused by empty pinctrl node
+ * or typing error) ther is no need remember this, so just
+ * return.
+ */
+ dev_info(p->dev,
+ "there is not valid maps for state %s\n", statename);
+ return 0;
+ }
/* Stash the mapping table chunk away for later use */
return dt_remember_or_free_map(p, statename, pctldev, map, num_maps);
@@ -166,21 +191,6 @@ static int dt_remember_dummy_state(struct pinctrl *p, const char *statename)
return dt_remember_or_free_map(p, statename, NULL, map, 1);
}
-bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev)
-{
- struct device_node *np;
- struct property *prop;
- int size;
-
- np = pctldev->dev->of_node;
- if (!np)
- return false;
-
- prop = of_find_property(np, "pinctrl-0", &size);
-
- return prop ? true : false;
-}
-
int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
{
struct device_node *np = p->dev->of_node;