[RAMEN9610-19588][COMMON] pinctrl: samsung: Add Exynos pin debug state
authorJaehyoung Choi <jkkkkk.choi@samsung.com>
Tue, 21 May 2019 04:34:05 +0000 (13:34 +0900)
committerKim Gunho <gunho.kim@samsung.com>
Mon, 9 Sep 2019 11:05:39 +0000 (20:05 +0900)
In pin drvdata, you can see the current status of each pin.

Change-Id: I1eca9c3e5cbff60fba4bda6530a9f8435eaab28b
Signed-off-by: Jaehyoung Choi <jkkkkk.choi@samsung.com>
Signed-off-by: Shinbeom Choi <sbeom.choi@samsung.com>
Signed-off-by: Kim Gunho <gunho.kim@samsung.com>
drivers/pinctrl/samsung/pinctrl-exynos.c
drivers/pinctrl/samsung/pinctrl-samsung.c
drivers/pinctrl/samsung/pinctrl-samsung.h

index e75c2552c6d9ce497557f4bd294300f91de7ab98..7004c67235edb5f337f5b8765dca9b20f64f59e5 100644 (file)
@@ -154,7 +154,7 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
        const struct samsung_pin_bank_type *bank_type = bank->type;
        unsigned long reg_con, flags;
-       unsigned int shift, mask, con;
+       unsigned int shift, mask, con, pin;
        int ret;
 
        ret = gpiochip_lock_as_irq(&bank->gpio_chip, irqd->hwirq);
@@ -176,6 +176,8 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
        con |= EXYNOS_PIN_FUNC_EINT << shift;
        writel(con, bank->pctl_base + reg_con);
 
+       pin = bank->grange.pin_base + irqd->hwirq - bank->drvdata->pin_base;
+       bank->drvdata->pin_groups[pin].state[PINCFG_TYPE_FUNC] = EXYNOS_PIN_FUNC_EINT;
        spin_unlock_irqrestore(&bank->slock, flags);
 
        return 0;
index 318f52f6d380e10bec3038e1d458a98b4acf295d..685a4a20a92654bb4226e662491d7cac81b7ea9f 100644 (file)
@@ -448,8 +448,12 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
        data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
        data &= ~(mask << shift);
        data |= func->val << shift;
+
        writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
 
+       drvdata->pin_groups[grp->pins[0] - drvdata->pin_base].state[PINCFG_TYPE_FUNC] =
+               ((data >> shift) & mask);
+
        spin_unlock_irqrestore(&bank->slock, flags);
 }
 
@@ -503,8 +507,11 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
        if (set) {
                cfg_value = PINCFG_UNPACK_VALUE(*config);
                data &= ~(mask << shift);
+
                data |= (cfg_value << shift);
                writel(data, reg_base + cfg_reg);
+               drvdata->pin_groups[pin - drvdata->pin_base].state[cfg_type] =
+                       ((data >> shift) & mask);
        } else {
                data >>= shift;
                data &= mask;
@@ -636,15 +643,18 @@ static void samsung_gpio_set_value(struct gpio_chip *gc,
        struct samsung_pin_bank *bank = gpiochip_get_data(gc);
        const struct samsung_pin_bank_type *type = bank->type;
        void __iomem *reg;
-       u32 data;
+       u32 data, pin;
 
        reg = bank->pctl_base + bank->pctl_offset;
+       pin = bank->grange.pin_base + offset - bank->drvdata->pin_base;
 
        data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);
        data &= ~(1 << offset);
        if (value)
                data |= 1 << offset;
        writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]);
+
+       bank->drvdata->pin_groups[pin].state[PINCFG_TYPE_DAT] = value;
 }
 
 /* gpiolib gpio_set callback function */
@@ -686,13 +696,14 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc,
        const struct samsung_pin_bank_type *type;
        struct samsung_pin_bank *bank;
        void __iomem *reg;
-       u32 data, mask, shift;
+       u32 pin, data, mask, shift;
 
        bank = gpiochip_get_data(gc);
        type = bank->type;
 
        reg = bank->pctl_base + bank->pctl_offset
                        + type->reg_offset[PINCFG_TYPE_FUNC];
+       pin = bank->grange.pin_base + offset - bank->drvdata->pin_base;
 
        mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
        shift = offset * type->fld_width[PINCFG_TYPE_FUNC];
@@ -704,8 +715,12 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc,
 
        data = readl(reg);
        data &= ~(mask << shift);
-       if (!input)
+
+       if (!input) {
                data |= EXYNOS_PIN_FUNC_OUTPUT << shift;
+               bank->drvdata->pin_groups[pin].state[PINCFG_TYPE_FUNC] = EXYNOS_PIN_FUNC_OUTPUT;
+       } else
+               bank->drvdata->pin_groups[pin].state[PINCFG_TYPE_FUNC] = EXYNOS_PIN_FUNC_INPUT;
        writel(data, reg);
 
        return 0;
@@ -1064,6 +1079,47 @@ static int samsung_gpiolib_register(struct platform_device *pdev,
        return 0;
 }
 
+static int samsung_pinctrl_debug_set(struct samsung_pinctrl_drv_data *drvdata) {
+       struct samsung_pin_bank *bank;
+       void __iomem *reg_base;
+       u32 pin_offset;
+       unsigned long flags;
+       enum pincfg_type cfg_type;
+       const struct samsung_pin_bank_type *type;
+       u32 data, width, mask, shift, cfg_reg;
+       int i;
+
+       for (i = 0; i < drvdata->pctl_dev->desc->npins; i++) {
+
+               pin_to_reg_bank(drvdata, i, &reg_base,
+                               &pin_offset, &bank);
+               drvdata->pin_groups[i].state_num = 0;
+               for (cfg_type = 0; cfg_type < PINCFG_TYPE_NUM; cfg_type++) {
+
+                       type = bank->type;
+                       if (!type->fld_width[cfg_type])
+                               continue;
+
+                       spin_lock_irqsave(&bank->slock, flags);
+                       width = type->fld_width[cfg_type];
+                       cfg_reg = type->reg_offset[cfg_type];
+                       mask = (1 << width) - 1;
+                       shift = pin_offset * width;
+
+                       data = readl(reg_base + cfg_reg);
+
+                       data >>= shift;
+                       data &= mask;
+
+                       drvdata->pin_groups[i].state[cfg_type] = data;
+                       drvdata->pin_groups[i].state_num++;
+                       spin_unlock_irqrestore(&bank->slock, flags);
+               }
+       }
+
+       return 0;
+}
+
 static const struct samsung_pin_ctrl *
 samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
 {
@@ -1225,6 +1281,7 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
        /* Add to the global list */
        list_add_tail(&drvdata->node, &drvdata_list);
 
+       samsung_pinctrl_debug_set(drvdata);
        return 0;
 }
 
index 2b9b6c659f8bb994295970ccbd2db39f58f0f33a..efe7a56211ecd442ab1926f12caf2616264ed8d7 100644 (file)
@@ -273,7 +273,7 @@ struct samsung_pinctrl_drv_data {
        struct pinctrl_desc             pctl;
        struct pinctrl_dev              *pctl_dev;
 
-       const struct samsung_pin_group  *pin_groups;
+       struct samsung_pin_group        *pin_groups;
        unsigned int                    nr_groups;
        const struct samsung_pmx_func   *pmx_functions;
        unsigned int                    nr_functions;
@@ -305,12 +305,15 @@ struct samsung_pinctrl_of_match_data {
  * @pins: the pins included in this group.
  * @num_pins: number of pins included in this group.
  * @func: the function number to be programmed when selected.
+ * @state: current pin group state.
  */
 struct samsung_pin_group {
        const char              *name;
        const unsigned int      *pins;
        u8                      num_pins;
        u8                      func;
+       unsigned int            state[PINCFG_TYPE_NUM];
+       unsigned int            state_num;
 };
 
 /**