diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2014-11-03 09:41:27 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-11-03 09:41:27 -0500 |
commit | 13d6a11af6de385f47603fac4538c504f574b67d (patch) | |
tree | c703c3e2ec8196a873958ab4c42454ff315797c0 | |
parent | 0c49e2f668a50783519ed7de8f938ad12746cdc2 (diff) | |
parent | 8dca9331270240125fedbe83e0a2cd5750ed9fff (diff) |
Merge tag 'v3.19-rockchip-pinctrl1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into devel
Rockchip-pinctrl fixes from Doug Anderson and suspend-specific
functions from Chris Zhong
-rw-r--r-- | drivers/pinctrl/pinctrl-rockchip.c | 116 |
1 files changed, 94 insertions, 22 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 016f4578e494..40970c305dd0 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c | |||
@@ -856,27 +856,22 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, | |||
856 | * leads to this function call (via the pinctrl_gpio_direction_{input|output}() | 856 | * leads to this function call (via the pinctrl_gpio_direction_{input|output}() |
857 | * function called from the gpiolib interface). | 857 | * function called from the gpiolib interface). |
858 | */ | 858 | */ |
859 | static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, | 859 | static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip, |
860 | struct pinctrl_gpio_range *range, | 860 | int pin, bool input) |
861 | unsigned offset, bool input) | ||
862 | { | 861 | { |
863 | struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
864 | struct rockchip_pin_bank *bank; | 862 | struct rockchip_pin_bank *bank; |
865 | struct gpio_chip *chip; | 863 | int ret; |
866 | int pin, ret; | 864 | unsigned long flags; |
867 | u32 data; | 865 | u32 data; |
868 | 866 | ||
869 | chip = range->gc; | ||
870 | bank = gc_to_pin_bank(chip); | 867 | bank = gc_to_pin_bank(chip); |
871 | pin = offset - chip->base; | ||
872 | |||
873 | dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", | ||
874 | offset, range->name, pin, input ? "input" : "output"); | ||
875 | 868 | ||
876 | ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); | 869 | ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); |
877 | if (ret < 0) | 870 | if (ret < 0) |
878 | return ret; | 871 | return ret; |
879 | 872 | ||
873 | spin_lock_irqsave(&bank->slock, flags); | ||
874 | |||
880 | data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); | 875 | data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); |
881 | /* set bit to 1 for output, 0 for input */ | 876 | /* set bit to 1 for output, 0 for input */ |
882 | if (!input) | 877 | if (!input) |
@@ -885,9 +880,28 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, | |||
885 | data &= ~BIT(pin); | 880 | data &= ~BIT(pin); |
886 | writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); | 881 | writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); |
887 | 882 | ||
883 | spin_unlock_irqrestore(&bank->slock, flags); | ||
884 | |||
888 | return 0; | 885 | return 0; |
889 | } | 886 | } |
890 | 887 | ||
888 | static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, | ||
889 | struct pinctrl_gpio_range *range, | ||
890 | unsigned offset, bool input) | ||
891 | { | ||
892 | struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
893 | struct gpio_chip *chip; | ||
894 | int pin; | ||
895 | |||
896 | chip = range->gc; | ||
897 | pin = offset - chip->base; | ||
898 | dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", | ||
899 | offset, range->name, pin, input ? "input" : "output"); | ||
900 | |||
901 | return _rockchip_pmx_gpio_set_direction(chip, offset - chip->base, | ||
902 | input); | ||
903 | } | ||
904 | |||
891 | static const struct pinmux_ops rockchip_pmx_ops = { | 905 | static const struct pinmux_ops rockchip_pmx_ops = { |
892 | .get_functions_count = rockchip_pmx_get_funcs_count, | 906 | .get_functions_count = rockchip_pmx_get_funcs_count, |
893 | .get_function_name = rockchip_pmx_get_func_name, | 907 | .get_function_name = rockchip_pmx_get_func_name, |
@@ -917,8 +931,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, | |||
917 | return false; | 931 | return false; |
918 | } | 932 | } |
919 | 933 | ||
920 | static int rockchip_gpio_direction_output(struct gpio_chip *gc, | 934 | static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value); |
921 | unsigned offset, int value); | ||
922 | static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); | 935 | static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); |
923 | 936 | ||
924 | /* set the pin config settings for a specified pin */ | 937 | /* set the pin config settings for a specified pin */ |
@@ -959,9 +972,10 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, | |||
959 | return rc; | 972 | return rc; |
960 | break; | 973 | break; |
961 | case PIN_CONFIG_OUTPUT: | 974 | case PIN_CONFIG_OUTPUT: |
962 | rc = rockchip_gpio_direction_output(&bank->gpio_chip, | 975 | rockchip_gpio_set(&bank->gpio_chip, |
963 | pin - bank->pin_base, | 976 | pin - bank->pin_base, arg); |
964 | arg); | 977 | rc = _rockchip_pmx_gpio_set_direction(&bank->gpio_chip, |
978 | pin - bank->pin_base, false); | ||
965 | if (rc) | 979 | if (rc) |
966 | return rc; | 980 | return rc; |
967 | break; | 981 | break; |
@@ -1253,6 +1267,10 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, | |||
1253 | } | 1267 | } |
1254 | } | 1268 | } |
1255 | 1269 | ||
1270 | ret = rockchip_pinctrl_parse_dt(pdev, info); | ||
1271 | if (ret) | ||
1272 | return ret; | ||
1273 | |||
1256 | info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); | 1274 | info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); |
1257 | if (!info->pctl_dev) { | 1275 | if (!info->pctl_dev) { |
1258 | dev_err(&pdev->dev, "could not register pinctrl driver\n"); | 1276 | dev_err(&pdev->dev, "could not register pinctrl driver\n"); |
@@ -1270,12 +1288,6 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, | |||
1270 | pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); | 1288 | pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); |
1271 | } | 1289 | } |
1272 | 1290 | ||
1273 | ret = rockchip_pinctrl_parse_dt(pdev, info); | ||
1274 | if (ret) { | ||
1275 | pinctrl_unregister(info->pctl_dev); | ||
1276 | return ret; | ||
1277 | } | ||
1278 | |||
1279 | return 0; | 1291 | return 0; |
1280 | } | 1292 | } |
1281 | 1293 | ||
@@ -1387,6 +1399,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1387 | u32 polarity = 0, data = 0; | 1399 | u32 polarity = 0, data = 0; |
1388 | u32 pend; | 1400 | u32 pend; |
1389 | bool edge_changed = false; | 1401 | bool edge_changed = false; |
1402 | unsigned long flags; | ||
1390 | 1403 | ||
1391 | dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); | 1404 | dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); |
1392 | 1405 | ||
@@ -1432,10 +1445,14 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1432 | 1445 | ||
1433 | if (bank->toggle_edge_mode && edge_changed) { | 1446 | if (bank->toggle_edge_mode && edge_changed) { |
1434 | /* Interrupt params should only be set with ints disabled */ | 1447 | /* Interrupt params should only be set with ints disabled */ |
1448 | spin_lock_irqsave(&bank->slock, flags); | ||
1449 | |||
1435 | data = readl_relaxed(bank->reg_base + GPIO_INTEN); | 1450 | data = readl_relaxed(bank->reg_base + GPIO_INTEN); |
1436 | writel_relaxed(0, bank->reg_base + GPIO_INTEN); | 1451 | writel_relaxed(0, bank->reg_base + GPIO_INTEN); |
1437 | writel(polarity, bank->reg_base + GPIO_INT_POLARITY); | 1452 | writel(polarity, bank->reg_base + GPIO_INT_POLARITY); |
1438 | writel(data, bank->reg_base + GPIO_INTEN); | 1453 | writel(data, bank->reg_base + GPIO_INTEN); |
1454 | |||
1455 | spin_unlock_irqrestore(&bank->slock, flags); | ||
1439 | } | 1456 | } |
1440 | 1457 | ||
1441 | chained_irq_exit(chip, desc); | 1458 | chained_irq_exit(chip, desc); |
@@ -1449,6 +1466,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |||
1449 | u32 polarity; | 1466 | u32 polarity; |
1450 | u32 level; | 1467 | u32 level; |
1451 | u32 data; | 1468 | u32 data; |
1469 | unsigned long flags; | ||
1452 | int ret; | 1470 | int ret; |
1453 | 1471 | ||
1454 | /* make sure the pin is configured as gpio input */ | 1472 | /* make sure the pin is configured as gpio input */ |
@@ -1456,15 +1474,20 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |||
1456 | if (ret < 0) | 1474 | if (ret < 0) |
1457 | return ret; | 1475 | return ret; |
1458 | 1476 | ||
1477 | spin_lock_irqsave(&bank->slock, flags); | ||
1478 | |||
1459 | data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); | 1479 | data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); |
1460 | data &= ~mask; | 1480 | data &= ~mask; |
1461 | writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); | 1481 | writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); |
1462 | 1482 | ||
1483 | spin_unlock_irqrestore(&bank->slock, flags); | ||
1484 | |||
1463 | if (type & IRQ_TYPE_EDGE_BOTH) | 1485 | if (type & IRQ_TYPE_EDGE_BOTH) |
1464 | __irq_set_handler_locked(d->irq, handle_edge_irq); | 1486 | __irq_set_handler_locked(d->irq, handle_edge_irq); |
1465 | else | 1487 | else |
1466 | __irq_set_handler_locked(d->irq, handle_level_irq); | 1488 | __irq_set_handler_locked(d->irq, handle_level_irq); |
1467 | 1489 | ||
1490 | spin_lock_irqsave(&bank->slock, flags); | ||
1468 | irq_gc_lock(gc); | 1491 | irq_gc_lock(gc); |
1469 | 1492 | ||
1470 | level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); | 1493 | level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); |
@@ -1507,6 +1530,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |||
1507 | break; | 1530 | break; |
1508 | default: | 1531 | default: |
1509 | irq_gc_unlock(gc); | 1532 | irq_gc_unlock(gc); |
1533 | spin_unlock_irqrestore(&bank->slock, flags); | ||
1510 | return -EINVAL; | 1534 | return -EINVAL; |
1511 | } | 1535 | } |
1512 | 1536 | ||
@@ -1514,6 +1538,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |||
1514 | writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); | 1538 | writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); |
1515 | 1539 | ||
1516 | irq_gc_unlock(gc); | 1540 | irq_gc_unlock(gc); |
1541 | spin_unlock_irqrestore(&bank->slock, flags); | ||
1517 | 1542 | ||
1518 | return 0; | 1543 | return 0; |
1519 | } | 1544 | } |
@@ -1563,6 +1588,7 @@ static int rockchip_interrupts_register(struct platform_device *pdev, | |||
1563 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; | 1588 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; |
1564 | gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; | 1589 | gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; |
1565 | gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; | 1590 | gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; |
1591 | gc->wake_enabled = IRQ_MSK(bank->nr_pins); | ||
1566 | 1592 | ||
1567 | irq_set_handler_data(bank->irq, bank); | 1593 | irq_set_handler_data(bank->irq, bank); |
1568 | irq_set_chained_handler(bank->irq, rockchip_irq_demux); | 1594 | irq_set_chained_handler(bank->irq, rockchip_irq_demux); |
@@ -1770,6 +1796,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( | |||
1770 | return ctrl; | 1796 | return ctrl; |
1771 | } | 1797 | } |
1772 | 1798 | ||
1799 | #define RK3288_GRF_GPIO6C_IOMUX 0x64 | ||
1800 | #define GPIO6C6_SEL_WRITE_ENABLE BIT(28) | ||
1801 | |||
1802 | static u32 rk3288_grf_gpio6c_iomux; | ||
1803 | |||
1804 | static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev) | ||
1805 | { | ||
1806 | struct rockchip_pinctrl *info = dev_get_drvdata(dev); | ||
1807 | int ret = pinctrl_force_sleep(info->pctl_dev); | ||
1808 | |||
1809 | if (ret) | ||
1810 | return ret; | ||
1811 | |||
1812 | /* | ||
1813 | * RK3288 GPIO6_C6 mux would be modified by Maskrom when resume, so save | ||
1814 | * the setting here, and restore it at resume. | ||
1815 | */ | ||
1816 | if (info->ctrl->type == RK3288) { | ||
1817 | ret = regmap_read(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, | ||
1818 | &rk3288_grf_gpio6c_iomux); | ||
1819 | if (ret) { | ||
1820 | pinctrl_force_default(info->pctl_dev); | ||
1821 | return ret; | ||
1822 | } | ||
1823 | } | ||
1824 | |||
1825 | return 0; | ||
1826 | } | ||
1827 | |||
1828 | static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) | ||
1829 | { | ||
1830 | struct rockchip_pinctrl *info = dev_get_drvdata(dev); | ||
1831 | int ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, | ||
1832 | rk3288_grf_gpio6c_iomux | | ||
1833 | GPIO6C6_SEL_WRITE_ENABLE); | ||
1834 | |||
1835 | if (ret) | ||
1836 | return ret; | ||
1837 | |||
1838 | return pinctrl_force_default(info->pctl_dev); | ||
1839 | } | ||
1840 | |||
1841 | static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend, | ||
1842 | rockchip_pinctrl_resume); | ||
1843 | |||
1773 | static int rockchip_pinctrl_probe(struct platform_device *pdev) | 1844 | static int rockchip_pinctrl_probe(struct platform_device *pdev) |
1774 | { | 1845 | { |
1775 | struct rockchip_pinctrl *info; | 1846 | struct rockchip_pinctrl *info; |
@@ -1983,6 +2054,7 @@ static struct platform_driver rockchip_pinctrl_driver = { | |||
1983 | .driver = { | 2054 | .driver = { |
1984 | .name = "rockchip-pinctrl", | 2055 | .name = "rockchip-pinctrl", |
1985 | .owner = THIS_MODULE, | 2056 | .owner = THIS_MODULE, |
2057 | .pm = &rockchip_pinctrl_dev_pm_ops, | ||
1986 | .of_match_table = rockchip_pinctrl_dt_match, | 2058 | .of_match_table = rockchip_pinctrl_dt_match, |
1987 | }, | 2059 | }, |
1988 | }; | 2060 | }; |