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 | ||
