summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2017-01-26 04:29:25 -0500
committerLinus Walleij <linus.walleij@linaro.org>2017-01-26 10:56:57 -0500
commit07731019c59c06e257aac351d774b2292c251dde (patch)
treef9690b493f3bb0fb217f0e630de974cb0c121276 /drivers/pinctrl
parent545e3e7da3d1356d3416faea2a8f94488c7a0056 (diff)
pinctrl: samsung: Move retention control from mach-exynos to the pinctrl driver
This patch moves pad retention control from PMU driver to Exynos pin controller driver. This helps to avoid possible ordering and logical dependencies between machine, PMU and pin control code. Till now it worked fine only because sys_ops for PMU and pin controller were called in registration order. This is also a preparation for adding new features to Exynos pin controller driver, like runtime power management and suspending individual pin controllers, which might be a part of some power domain. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org> Acked-by: Tomasz Figa <tomasz.figa@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 53baafdad51b..c81df3c843c3 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -28,7 +28,10 @@
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/regmap.h>
31#include <linux/err.h> 32#include <linux/err.h>
33#include <linux/soc/samsung/exynos-pmu.h>
34#include <linux/soc/samsung/exynos-regs-pmu.h>
32 35
33#include "pinctrl-samsung.h" 36#include "pinctrl-samsung.h"
34#include "pinctrl-exynos.h" 37#include "pinctrl-exynos.h"
@@ -679,6 +682,54 @@ const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = {
679 }, 682 },
680}; 683};
681 684
685/* Pad retention control code for accessing PMU regmap */
686static atomic_t exynos_shared_retention_refcnt;
687
688static void exynos_retention_enable(struct samsung_pinctrl_drv_data *drvdata)
689{
690 if (drvdata->retention_ctrl->refcnt)
691 atomic_inc(drvdata->retention_ctrl->refcnt);
692}
693
694static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata)
695{
696 struct samsung_retention_ctrl *ctrl = drvdata->retention_ctrl;
697 struct regmap *pmu_regs = ctrl->priv;
698 int i;
699
700 if (ctrl->refcnt && !atomic_dec_and_test(ctrl->refcnt))
701 return;
702
703 for (i = 0; i < ctrl->nr_regs; i++)
704 regmap_write(pmu_regs, ctrl->regs[i], ctrl->value);
705}
706
707static struct samsung_retention_ctrl *
708exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
709 const struct samsung_retention_data *data)
710{
711 struct samsung_retention_ctrl *ctrl;
712 struct regmap *pmu_regs;
713
714 ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL);
715 if (!ctrl)
716 return ERR_PTR(-ENOMEM);
717
718 pmu_regs = exynos_get_pmu_regmap();
719 if (IS_ERR(pmu_regs))
720 return ERR_CAST(pmu_regs);
721
722 ctrl->priv = pmu_regs;
723 ctrl->regs = data->regs;
724 ctrl->nr_regs = data->nr_regs;
725 ctrl->value = data->value;
726 ctrl->refcnt = data->refcnt;
727 ctrl->enable = exynos_retention_enable;
728 ctrl->disable = exynos_retention_disable;
729
730 return ctrl;
731}
732
682/* pin banks of exynos3250 pin-controller 0 */ 733/* pin banks of exynos3250 pin-controller 0 */
683static const struct samsung_pin_bank_data exynos3250_pin_banks0[] __initconst = { 734static const struct samsung_pin_bank_data exynos3250_pin_banks0[] __initconst = {
684 EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), 735 EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
@@ -711,6 +762,30 @@ static const struct samsung_pin_bank_data exynos3250_pin_banks1[] __initconst =
711}; 762};
712 763
713/* 764/*
765 * PMU pad retention groups for Exynos3250 doesn't match pin banks, so handle
766 * them all together
767 */
768static const u32 exynos3250_retention_regs[] = {
769 S5P_PAD_RET_MAUDIO_OPTION,
770 S5P_PAD_RET_GPIO_OPTION,
771 S5P_PAD_RET_UART_OPTION,
772 S5P_PAD_RET_MMCA_OPTION,
773 S5P_PAD_RET_MMCB_OPTION,
774 S5P_PAD_RET_EBIA_OPTION,
775 S5P_PAD_RET_EBIB_OPTION,
776 S5P_PAD_RET_MMC2_OPTION,
777 S5P_PAD_RET_SPI_OPTION,
778};
779
780static const struct samsung_retention_data exynos3250_retention_data __initconst = {
781 .regs = exynos3250_retention_regs,
782 .nr_regs = ARRAY_SIZE(exynos3250_retention_regs),
783 .value = EXYNOS_WAKEUP_FROM_LOWPWR,
784 .refcnt = &exynos_shared_retention_refcnt,
785 .init = exynos_retention_init,
786};
787
788/*
714 * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes 789 * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes
715 * two gpio/pin-mux/pinconfig controllers. 790 * two gpio/pin-mux/pinconfig controllers.
716 */ 791 */
@@ -722,6 +797,7 @@ const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = {
722 .eint_gpio_init = exynos_eint_gpio_init, 797 .eint_gpio_init = exynos_eint_gpio_init,
723 .suspend = exynos_pinctrl_suspend, 798 .suspend = exynos_pinctrl_suspend,
724 .resume = exynos_pinctrl_resume, 799 .resume = exynos_pinctrl_resume,
800 .retention_data = &exynos3250_retention_data,
725 }, { 801 }, {
726 /* pin-controller instance 1 data */ 802 /* pin-controller instance 1 data */
727 .pin_banks = exynos3250_pin_banks1, 803 .pin_banks = exynos3250_pin_banks1,
@@ -730,6 +806,7 @@ const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = {
730 .eint_wkup_init = exynos_eint_wkup_init, 806 .eint_wkup_init = exynos_eint_wkup_init,
731 .suspend = exynos_pinctrl_suspend, 807 .suspend = exynos_pinctrl_suspend,
732 .resume = exynos_pinctrl_resume, 808 .resume = exynos_pinctrl_resume,
809 .retention_data = &exynos3250_retention_data,
733 }, 810 },
734}; 811};
735 812
@@ -782,6 +859,36 @@ static const struct samsung_pin_bank_data exynos4210_pin_banks2[] __initconst =
782 EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"), 859 EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"),
783}; 860};
784 861
862/* PMU pad retention groups registers for Exynos4 (without audio) */
863static const u32 exynos4_retention_regs[] = {
864 S5P_PAD_RET_GPIO_OPTION,
865 S5P_PAD_RET_UART_OPTION,
866 S5P_PAD_RET_MMCA_OPTION,
867 S5P_PAD_RET_MMCB_OPTION,
868 S5P_PAD_RET_EBIA_OPTION,
869 S5P_PAD_RET_EBIB_OPTION,
870};
871
872static const struct samsung_retention_data exynos4_retention_data __initconst = {
873 .regs = exynos4_retention_regs,
874 .nr_regs = ARRAY_SIZE(exynos4_retention_regs),
875 .value = EXYNOS_WAKEUP_FROM_LOWPWR,
876 .refcnt = &exynos_shared_retention_refcnt,
877 .init = exynos_retention_init,
878};
879
880/* PMU retention control for audio pins can be tied to audio pin bank */
881static const u32 exynos4_audio_retention_regs[] = {
882 S5P_PAD_RET_MAUDIO_OPTION,
883};
884
885static const struct samsung_retention_data exynos4_audio_retention_data __initconst = {
886 .regs = exynos4_audio_retention_regs,
887 .nr_regs = ARRAY_SIZE(exynos4_audio_retention_regs),
888 .value = EXYNOS_WAKEUP_FROM_LOWPWR,
889 .init = exynos_retention_init,
890};
891
785/* 892/*
786 * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes 893 * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
787 * three gpio/pin-mux/pinconfig controllers. 894 * three gpio/pin-mux/pinconfig controllers.
@@ -794,6 +901,7 @@ const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = {
794 .eint_gpio_init = exynos_eint_gpio_init, 901 .eint_gpio_init = exynos_eint_gpio_init,
795 .suspend = exynos_pinctrl_suspend, 902 .suspend = exynos_pinctrl_suspend,
796 .resume = exynos_pinctrl_resume, 903 .resume = exynos_pinctrl_resume,
904 .retention_data = &exynos4_retention_data,
797 }, { 905 }, {
798 /* pin-controller instance 1 data */ 906 /* pin-controller instance 1 data */
799 .pin_banks = exynos4210_pin_banks1, 907 .pin_banks = exynos4210_pin_banks1,
@@ -802,10 +910,12 @@ const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = {
802 .eint_wkup_init = exynos_eint_wkup_init, 910 .eint_wkup_init = exynos_eint_wkup_init,
803 .suspend = exynos_pinctrl_suspend, 911 .suspend = exynos_pinctrl_suspend,
804 .resume = exynos_pinctrl_resume, 912 .resume = exynos_pinctrl_resume,
913 .retention_data = &exynos4_retention_data,
805 }, { 914 }, {
806 /* pin-controller instance 2 data */ 915 /* pin-controller instance 2 data */
807 .pin_banks = exynos4210_pin_banks2, 916 .pin_banks = exynos4210_pin_banks2,
808 .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), 917 .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2),
918 .retention_data = &exynos4_audio_retention_data,
809 }, 919 },
810}; 920};
811 921
@@ -879,6 +989,7 @@ const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
879 .eint_gpio_init = exynos_eint_gpio_init, 989 .eint_gpio_init = exynos_eint_gpio_init,
880 .suspend = exynos_pinctrl_suspend, 990 .suspend = exynos_pinctrl_suspend,
881 .resume = exynos_pinctrl_resume, 991 .resume = exynos_pinctrl_resume,
992 .retention_data = &exynos4_retention_data,
882 }, { 993 }, {
883 /* pin-controller instance 1 data */ 994 /* pin-controller instance 1 data */
884 .pin_banks = exynos4x12_pin_banks1, 995 .pin_banks = exynos4x12_pin_banks1,
@@ -887,6 +998,7 @@ const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
887 .eint_wkup_init = exynos_eint_wkup_init, 998 .eint_wkup_init = exynos_eint_wkup_init,
888 .suspend = exynos_pinctrl_suspend, 999 .suspend = exynos_pinctrl_suspend,
889 .resume = exynos_pinctrl_resume, 1000 .resume = exynos_pinctrl_resume,
1001 .retention_data = &exynos4_retention_data,
890 }, { 1002 }, {
891 /* pin-controller instance 2 data */ 1003 /* pin-controller instance 2 data */
892 .pin_banks = exynos4x12_pin_banks2, 1004 .pin_banks = exynos4x12_pin_banks2,
@@ -894,6 +1006,7 @@ const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
894 .eint_gpio_init = exynos_eint_gpio_init, 1006 .eint_gpio_init = exynos_eint_gpio_init,
895 .suspend = exynos_pinctrl_suspend, 1007 .suspend = exynos_pinctrl_suspend,
896 .resume = exynos_pinctrl_resume, 1008 .resume = exynos_pinctrl_resume,
1009 .retention_data = &exynos4_audio_retention_data,
897 }, { 1010 }, {
898 /* pin-controller instance 3 data */ 1011 /* pin-controller instance 3 data */
899 .pin_banks = exynos4x12_pin_banks3, 1012 .pin_banks = exynos4x12_pin_banks3,
@@ -973,6 +1086,7 @@ const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = {
973 .eint_wkup_init = exynos_eint_wkup_init, 1086 .eint_wkup_init = exynos_eint_wkup_init,
974 .suspend = exynos_pinctrl_suspend, 1087 .suspend = exynos_pinctrl_suspend,
975 .resume = exynos_pinctrl_resume, 1088 .resume = exynos_pinctrl_resume,
1089 .retention_data = &exynos4_retention_data,
976 }, { 1090 }, {
977 /* pin-controller instance 1 data */ 1091 /* pin-controller instance 1 data */
978 .pin_banks = exynos5250_pin_banks1, 1092 .pin_banks = exynos5250_pin_banks1,
@@ -980,6 +1094,7 @@ const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = {
980 .eint_gpio_init = exynos_eint_gpio_init, 1094 .eint_gpio_init = exynos_eint_gpio_init,
981 .suspend = exynos_pinctrl_suspend, 1095 .suspend = exynos_pinctrl_suspend,
982 .resume = exynos_pinctrl_resume, 1096 .resume = exynos_pinctrl_resume,
1097 .retention_data = &exynos4_retention_data,
983 }, { 1098 }, {
984 /* pin-controller instance 2 data */ 1099 /* pin-controller instance 2 data */
985 .pin_banks = exynos5250_pin_banks2, 1100 .pin_banks = exynos5250_pin_banks2,
@@ -994,6 +1109,7 @@ const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = {
994 .eint_gpio_init = exynos_eint_gpio_init, 1109 .eint_gpio_init = exynos_eint_gpio_init,
995 .suspend = exynos_pinctrl_suspend, 1110 .suspend = exynos_pinctrl_suspend,
996 .resume = exynos_pinctrl_resume, 1111 .resume = exynos_pinctrl_resume,
1112 .retention_data = &exynos4_audio_retention_data,
997 }, 1113 },
998}; 1114};
999 1115
@@ -1220,6 +1336,30 @@ static const struct samsung_pin_bank_data exynos5420_pin_banks4[] __initconst =
1220 EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), 1336 EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
1221}; 1337};
1222 1338
1339/* PMU pad retention groups registers for Exynos5420 (without audio) */
1340static const u32 exynos5420_retention_regs[] = {
1341 EXYNOS_PAD_RET_DRAM_OPTION,
1342 EXYNOS_PAD_RET_JTAG_OPTION,
1343 EXYNOS5420_PAD_RET_GPIO_OPTION,
1344 EXYNOS5420_PAD_RET_UART_OPTION,
1345 EXYNOS5420_PAD_RET_MMCA_OPTION,
1346 EXYNOS5420_PAD_RET_MMCB_OPTION,
1347 EXYNOS5420_PAD_RET_MMCC_OPTION,
1348 EXYNOS5420_PAD_RET_HSI_OPTION,
1349 EXYNOS_PAD_RET_EBIA_OPTION,
1350 EXYNOS_PAD_RET_EBIB_OPTION,
1351 EXYNOS5420_PAD_RET_SPI_OPTION,
1352 EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION,
1353};
1354
1355static const struct samsung_retention_data exynos5420_retention_data __initconst = {
1356 .regs = exynos5420_retention_regs,
1357 .nr_regs = ARRAY_SIZE(exynos5420_retention_regs),
1358 .value = EXYNOS_WAKEUP_FROM_LOWPWR,
1359 .refcnt = &exynos_shared_retention_refcnt,
1360 .init = exynos_retention_init,
1361};
1362
1223/* 1363/*
1224 * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes 1364 * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes
1225 * four gpio/pin-mux/pinconfig controllers. 1365 * four gpio/pin-mux/pinconfig controllers.
@@ -1231,26 +1371,31 @@ const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = {
1231 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks0), 1371 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks0),
1232 .eint_gpio_init = exynos_eint_gpio_init, 1372 .eint_gpio_init = exynos_eint_gpio_init,
1233 .eint_wkup_init = exynos_eint_wkup_init, 1373 .eint_wkup_init = exynos_eint_wkup_init,
1374 .retention_data = &exynos5420_retention_data,
1234 }, { 1375 }, {
1235 /* pin-controller instance 1 data */ 1376 /* pin-controller instance 1 data */
1236 .pin_banks = exynos5420_pin_banks1, 1377 .pin_banks = exynos5420_pin_banks1,
1237 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks1), 1378 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks1),
1238 .eint_gpio_init = exynos_eint_gpio_init, 1379 .eint_gpio_init = exynos_eint_gpio_init,
1380 .retention_data = &exynos5420_retention_data,
1239 }, { 1381 }, {
1240 /* pin-controller instance 2 data */ 1382 /* pin-controller instance 2 data */
1241 .pin_banks = exynos5420_pin_banks2, 1383 .pin_banks = exynos5420_pin_banks2,
1242 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks2), 1384 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks2),
1243 .eint_gpio_init = exynos_eint_gpio_init, 1385 .eint_gpio_init = exynos_eint_gpio_init,
1386 .retention_data = &exynos5420_retention_data,
1244 }, { 1387 }, {
1245 /* pin-controller instance 3 data */ 1388 /* pin-controller instance 3 data */
1246 .pin_banks = exynos5420_pin_banks3, 1389 .pin_banks = exynos5420_pin_banks3,
1247 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks3), 1390 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks3),
1248 .eint_gpio_init = exynos_eint_gpio_init, 1391 .eint_gpio_init = exynos_eint_gpio_init,
1392 .retention_data = &exynos5420_retention_data,
1249 }, { 1393 }, {
1250 /* pin-controller instance 4 data */ 1394 /* pin-controller instance 4 data */
1251 .pin_banks = exynos5420_pin_banks4, 1395 .pin_banks = exynos5420_pin_banks4,
1252 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks4), 1396 .nr_banks = ARRAY_SIZE(exynos5420_pin_banks4),
1253 .eint_gpio_init = exynos_eint_gpio_init, 1397 .eint_gpio_init = exynos_eint_gpio_init,
1398 .retention_data = &exynos4_audio_retention_data,
1254 }, 1399 },
1255}; 1400};
1256 1401