diff options
Diffstat (limited to 'drivers/mfd/sm501.c')
-rw-r--r-- | drivers/mfd/sm501.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 170f9d47c2f9..0e5761f12634 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
@@ -41,6 +41,7 @@ struct sm501_gpio_chip { | |||
41 | struct gpio_chip gpio; | 41 | struct gpio_chip gpio; |
42 | struct sm501_gpio *ourgpio; /* to get back to parent. */ | 42 | struct sm501_gpio *ourgpio; /* to get back to parent. */ |
43 | void __iomem *regbase; | 43 | void __iomem *regbase; |
44 | void __iomem *control; /* address of control reg. */ | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | struct sm501_gpio { | 47 | struct sm501_gpio { |
@@ -908,6 +909,25 @@ static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset) | |||
908 | return result & 1UL; | 909 | return result & 1UL; |
909 | } | 910 | } |
910 | 911 | ||
912 | static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip, | ||
913 | unsigned long bit) | ||
914 | { | ||
915 | unsigned long ctrl; | ||
916 | |||
917 | /* check and modify if this pin is not set as gpio. */ | ||
918 | |||
919 | if (readl(smchip->control) & bit) { | ||
920 | dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev, | ||
921 | "changing mode of gpio, bit %08lx\n", bit); | ||
922 | |||
923 | ctrl = readl(smchip->control); | ||
924 | ctrl &= ~bit; | ||
925 | writel(ctrl, smchip->control); | ||
926 | |||
927 | sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio)); | ||
928 | } | ||
929 | } | ||
930 | |||
911 | static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 931 | static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
912 | 932 | ||
913 | { | 933 | { |
@@ -929,6 +949,8 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
929 | writel(val, regs); | 949 | writel(val, regs); |
930 | 950 | ||
931 | sm501_sync_regs(sm501_gpio_to_dev(smgpio)); | 951 | sm501_sync_regs(sm501_gpio_to_dev(smgpio)); |
952 | sm501_gpio_ensure_gpio(smchip, bit); | ||
953 | |||
932 | spin_unlock_irqrestore(&smgpio->lock, save); | 954 | spin_unlock_irqrestore(&smgpio->lock, save); |
933 | } | 955 | } |
934 | 956 | ||
@@ -941,8 +963,8 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset) | |||
941 | unsigned long save; | 963 | unsigned long save; |
942 | unsigned long ddr; | 964 | unsigned long ddr; |
943 | 965 | ||
944 | dev_info(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d)\n", | 966 | dev_dbg(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d)\n", |
945 | __func__, chip, offset); | 967 | __func__, chip, offset); |
946 | 968 | ||
947 | spin_lock_irqsave(&smgpio->lock, save); | 969 | spin_lock_irqsave(&smgpio->lock, save); |
948 | 970 | ||
@@ -950,6 +972,8 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset) | |||
950 | writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW); | 972 | writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW); |
951 | 973 | ||
952 | sm501_sync_regs(sm501_gpio_to_dev(smgpio)); | 974 | sm501_sync_regs(sm501_gpio_to_dev(smgpio)); |
975 | sm501_gpio_ensure_gpio(smchip, bit); | ||
976 | |||
953 | spin_unlock_irqrestore(&smgpio->lock, save); | 977 | spin_unlock_irqrestore(&smgpio->lock, save); |
954 | 978 | ||
955 | return 0; | 979 | return 0; |
@@ -1012,9 +1036,11 @@ static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm, | |||
1012 | if (base > 0) | 1036 | if (base > 0) |
1013 | base += 32; | 1037 | base += 32; |
1014 | chip->regbase = gpio->regs + SM501_GPIO_DATA_HIGH; | 1038 | chip->regbase = gpio->regs + SM501_GPIO_DATA_HIGH; |
1039 | chip->control = sm->regs + SM501_GPIO63_32_CONTROL; | ||
1015 | gchip->label = "SM501-HIGH"; | 1040 | gchip->label = "SM501-HIGH"; |
1016 | } else { | 1041 | } else { |
1017 | chip->regbase = gpio->regs + SM501_GPIO_DATA_LOW; | 1042 | chip->regbase = gpio->regs + SM501_GPIO_DATA_LOW; |
1043 | chip->control = sm->regs + SM501_GPIO31_0_CONTROL; | ||
1018 | gchip->label = "SM501-LOW"; | 1044 | gchip->label = "SM501-LOW"; |
1019 | } | 1045 | } |
1020 | 1046 | ||