summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/mediatek
diff options
context:
space:
mode:
authorSean Wang <sean.wang@mediatek.com>2018-09-08 07:07:37 -0400
committerLinus Walleij <linus.walleij@linaro.org>2018-09-18 17:53:37 -0400
commit89132dd8ffd2218fad3f53a9ca529e609237448a (patch)
tree937b21be21bbde3710b3933967a8e5b1cc46121e /drivers/pinctrl/mediatek
parent29686f0151dff68e623475d449f99d8124825b17 (diff)
pinctrl: mediatek: extend eint build to pinctrl-mtk-common-v2.c
Almost all MediaTek SoCs apply the exact same logic to build eint, so move the common functions into pinctrl-mtk-common-v2.c to allow each new pinctrl driver to reuse them. Also, add a protection checker on hw->soc->eint_hw to avoid invalid memory access when there's certain SoC not to define its eint_hw properly in the code flow. Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/mediatek')
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-moore.c124
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c135
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h2
3 files changed, 137 insertions, 124 deletions
diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c
index f0390b34cae5..7cfab0cfd18c 100644
--- a/drivers/pinctrl/mediatek/pinctrl-moore.c
+++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
@@ -584,130 +584,6 @@ static int mtk_build_functions(struct mtk_pinctrl *hw)
584 return 0; 584 return 0;
585} 585}
586 586
587static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw,
588 unsigned long eint_n)
589{
590 const struct mtk_pin_desc *desc;
591 int i = 0;
592
593 desc = (const struct mtk_pin_desc *)hw->soc->pins;
594
595 while (i < hw->soc->npins) {
596 if (desc[i].eint.eint_n == eint_n)
597 return desc[i].number;
598 i++;
599 }
600
601 return EINT_NA;
602}
603
604static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
605 unsigned int *gpio_n,
606 struct gpio_chip **gpio_chip)
607{
608 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
609 const struct mtk_pin_desc *desc;
610
611 desc = (const struct mtk_pin_desc *)hw->soc->pins;
612 *gpio_chip = &hw->chip;
613
614 /* Be greedy to guess first gpio_n is equal to eint_n */
615 if (desc[eint_n].eint.eint_n == eint_n)
616 *gpio_n = eint_n;
617 else
618 *gpio_n = mtk_xt_find_eint_num(hw, eint_n);
619
620 return *gpio_n == EINT_NA ? -EINVAL : 0;
621}
622
623static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
624{
625 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
626 struct gpio_chip *gpio_chip;
627 unsigned int gpio_n;
628 int err;
629
630 err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
631 if (err)
632 return err;
633
634 return mtk_gpio_get(gpio_chip, gpio_n);
635}
636
637static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
638{
639 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
640 const struct mtk_pin_desc *desc;
641 struct gpio_chip *gpio_chip;
642 unsigned int gpio_n;
643 int err;
644
645 err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
646 if (err)
647 return err;
648
649 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
650
651 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
652 desc->eint.eint_m);
653 if (err)
654 return err;
655
656 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT);
657 if (err)
658 return err;
659
660 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_ENABLE);
661 if (err)
662 return err;
663
664 return 0;
665}
666
667static const struct mtk_eint_xt mtk_eint_xt = {
668 .get_gpio_n = mtk_xt_get_gpio_n,
669 .get_gpio_state = mtk_xt_get_gpio_state,
670 .set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
671};
672
673static int
674mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
675{
676 struct device_node *np = pdev->dev.of_node;
677 struct resource *res;
678
679 if (!IS_ENABLED(CONFIG_EINT_MTK))
680 return 0;
681
682 if (!of_property_read_bool(np, "interrupt-controller"))
683 return -ENODEV;
684
685 hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
686 if (!hw->eint)
687 return -ENOMEM;
688
689 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eint");
690 if (!res) {
691 dev_err(&pdev->dev, "Unable to get eint resource\n");
692 return -ENODEV;
693 }
694
695 hw->eint->base = devm_ioremap_resource(&pdev->dev, res);
696 if (IS_ERR(hw->eint->base))
697 return PTR_ERR(hw->eint->base);
698
699 hw->eint->irq = irq_of_parse_and_map(np, 0);
700 if (!hw->eint->irq)
701 return -EINVAL;
702
703 hw->eint->dev = &pdev->dev;
704 hw->eint->hw = hw->soc->eint_hw;
705 hw->eint->pctl = hw;
706 hw->eint->gpio_xlate = &mtk_eint_xt;
707
708 return mtk_eint_do_init(hw->eint);
709}
710
711int mtk_moore_pinctrl_probe(struct platform_device *pdev, 587int mtk_moore_pinctrl_probe(struct platform_device *pdev,
712 const struct mtk_pin_soc *soc) 588 const struct mtk_pin_soc *soc)
713{ 589{
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 7d5f570d7211..e8a2066a4d15 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -9,8 +9,11 @@
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/err.h> 10#include <linux/err.h>
11#include <linux/gpio.h> 11#include <linux/gpio.h>
12#include <linux/platform_device.h>
12#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/of_irq.h>
13 15
16#include "mtk-eint.h"
14#include "pinctrl-mtk-common-v2.h" 17#include "pinctrl-mtk-common-v2.h"
15 18
16/** 19/**
@@ -207,6 +210,138 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
207 return 0; 210 return 0;
208} 211}
209 212
213static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
214{
215 const struct mtk_pin_desc *desc;
216 int i = 0;
217
218 desc = (const struct mtk_pin_desc *)hw->soc->pins;
219
220 while (i < hw->soc->npins) {
221 if (desc[i].eint.eint_n == eint_n)
222 return desc[i].number;
223 i++;
224 }
225
226 return EINT_NA;
227}
228
229static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
230 unsigned int *gpio_n,
231 struct gpio_chip **gpio_chip)
232{
233 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
234 const struct mtk_pin_desc *desc;
235
236 desc = (const struct mtk_pin_desc *)hw->soc->pins;
237 *gpio_chip = &hw->chip;
238
239 /* Be greedy to guess first gpio_n is equal to eint_n */
240 if (desc[eint_n].eint.eint_n == eint_n)
241 *gpio_n = eint_n;
242 else
243 *gpio_n = mtk_xt_find_eint_num(hw, eint_n);
244
245 return *gpio_n == EINT_NA ? -EINVAL : 0;
246}
247
248static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
249{
250 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
251 const struct mtk_pin_desc *desc;
252 struct gpio_chip *gpio_chip;
253 unsigned int gpio_n;
254 int value, err;
255
256 err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
257 if (err)
258 return err;
259
260 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
261
262 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
263 if (err)
264 return err;
265
266 return !!value;
267}
268
269static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
270{
271 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
272 const struct mtk_pin_desc *desc;
273 struct gpio_chip *gpio_chip;
274 unsigned int gpio_n;
275 int err;
276
277 err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
278 if (err)
279 return err;
280
281 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
282
283 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
284 desc->eint.eint_m);
285 if (err)
286 return err;
287
288 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT);
289 if (err)
290 return err;
291
292 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_ENABLE);
293 if (err)
294 return err;
295
296 return 0;
297}
298
299static const struct mtk_eint_xt mtk_eint_xt = {
300 .get_gpio_n = mtk_xt_get_gpio_n,
301 .get_gpio_state = mtk_xt_get_gpio_state,
302 .set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
303};
304
305int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
306{
307 struct device_node *np = pdev->dev.of_node;
308 struct resource *res;
309
310 if (!IS_ENABLED(CONFIG_EINT_MTK))
311 return 0;
312
313 if (!of_property_read_bool(np, "interrupt-controller"))
314 return -ENODEV;
315
316 hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
317 if (!hw->eint)
318 return -ENOMEM;
319
320 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eint");
321 if (!res) {
322 dev_err(&pdev->dev, "Unable to get eint resource\n");
323 return -ENODEV;
324 }
325
326 hw->eint->base = devm_ioremap_resource(&pdev->dev, res);
327 if (IS_ERR(hw->eint->base))
328 return PTR_ERR(hw->eint->base);
329
330 hw->eint->irq = irq_of_parse_and_map(np, 0);
331 if (!hw->eint->irq)
332 return -EINVAL;
333
334 if (!hw->soc->eint_hw)
335 return -ENODEV;
336
337 hw->eint->dev = &pdev->dev;
338 hw->eint->hw = hw->soc->eint_hw;
339 hw->eint->pctl = hw;
340 hw->eint->gpio_xlate = &mtk_eint_xt;
341
342 return mtk_eint_do_init(hw->eint);
343}
344
210/* Revision 0 */ 345/* Revision 0 */
211int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw, 346int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
212 const struct mtk_pin_desc *desc) 347 const struct mtk_pin_desc *desc)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 05b9b391afea..e0d4e68b7cdd 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -245,6 +245,8 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
245int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, 245int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
246 int field, int *value); 246 int field, int *value);
247 247
248int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev);
249
248int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw, 250int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
249 const struct mtk_pin_desc *desc); 251 const struct mtk_pin_desc *desc);
250int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw, 252int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,