Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: exar: switch to using regmap

We can simplify the code in gpio-exar by using regmap. This allows us to
drop the mutex (regmap provides its own locking) and we can also reuse
regmap's bit operations instead of implementing our own update function.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

+38 -54
+1
drivers/gpio/Kconfig
··· 255 255 config GPIO_EXAR 256 256 tristate "Support for GPIO pins on XR17V352/354/358" 257 257 depends on SERIAL_8250_EXAR 258 + select REGMAP_MMIO 258 259 help 259 260 Selecting this option will enable handling of GPIO pins present 260 261 on Exar XR17V352/354/358 chips.
+37 -54
drivers/gpio/gpio-exar.c
··· 14 14 #include <linux/module.h> 15 15 #include <linux/pci.h> 16 16 #include <linux/platform_device.h> 17 + #include <linux/regmap.h> 17 18 18 19 #define EXAR_OFFSET_MPIOLVL_LO 0x90 19 20 #define EXAR_OFFSET_MPIOSEL_LO 0x93 ··· 27 26 28 27 struct exar_gpio_chip { 29 28 struct gpio_chip gpio_chip; 30 - struct mutex lock; 29 + struct regmap *regmap; 31 30 int index; 32 - void __iomem *regs; 33 31 char name[20]; 34 32 unsigned int first_pin; 35 33 }; ··· 53 53 return (offset + exar_gpio->first_pin) % 8; 54 54 } 55 55 56 - static void exar_update(struct gpio_chip *chip, unsigned int reg, int val, 57 - unsigned int offset) 58 - { 59 - struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip); 60 - int temp; 61 - 62 - mutex_lock(&exar_gpio->lock); 63 - temp = readb(exar_gpio->regs + reg); 64 - temp &= ~BIT(offset); 65 - if (val) 66 - temp |= BIT(offset); 67 - writeb(temp, exar_gpio->regs + reg); 68 - mutex_unlock(&exar_gpio->lock); 69 - } 70 - 71 - static int exar_set_direction(struct gpio_chip *chip, int direction, 72 - unsigned int offset) 73 - { 74 - struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip); 75 - unsigned int addr = exar_offset_to_sel_addr(exar_gpio, offset); 76 - unsigned int bit = exar_offset_to_bit(exar_gpio, offset); 77 - 78 - exar_update(chip, addr, direction, bit); 79 - return 0; 80 - } 81 - 82 - static int exar_get(struct gpio_chip *chip, unsigned int reg) 83 - { 84 - struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip); 85 - int value; 86 - 87 - mutex_lock(&exar_gpio->lock); 88 - value = readb(exar_gpio->regs + reg); 89 - mutex_unlock(&exar_gpio->lock); 90 - 91 - return value; 92 - } 93 - 94 56 static int exar_get_direction(struct gpio_chip *chip, unsigned int offset) 95 57 { 96 58 struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip); 97 59 unsigned int addr = exar_offset_to_sel_addr(exar_gpio, offset); 98 60 unsigned int bit = exar_offset_to_bit(exar_gpio, offset); 99 61 100 - if (exar_get(chip, addr) & BIT(bit)) 62 + if (regmap_test_bits(exar_gpio->regmap, addr, BIT(bit))) 101 63 return GPIO_LINE_DIRECTION_IN; 102 64 103 65 return GPIO_LINE_DIRECTION_OUT; ··· 71 109 unsigned int addr = exar_offset_to_lvl_addr(exar_gpio, offset); 72 110 unsigned int bit = exar_offset_to_bit(exar_gpio, offset); 73 111 74 - return !!(exar_get(chip, addr) & BIT(bit)); 112 + return !!(regmap_test_bits(exar_gpio->regmap, addr, BIT(bit))); 75 113 } 76 114 77 115 static void exar_set_value(struct gpio_chip *chip, unsigned int offset, ··· 81 119 unsigned int addr = exar_offset_to_lvl_addr(exar_gpio, offset); 82 120 unsigned int bit = exar_offset_to_bit(exar_gpio, offset); 83 121 84 - exar_update(chip, addr, value, bit); 122 + if (value) 123 + regmap_set_bits(exar_gpio->regmap, addr, BIT(bit)); 124 + else 125 + regmap_clear_bits(exar_gpio->regmap, addr, BIT(bit)); 85 126 } 86 127 87 128 static int exar_direction_output(struct gpio_chip *chip, unsigned int offset, 88 129 int value) 89 130 { 131 + struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip); 132 + unsigned int addr = exar_offset_to_sel_addr(exar_gpio, offset); 133 + unsigned int bit = exar_offset_to_bit(exar_gpio, offset); 134 + 90 135 exar_set_value(chip, offset, value); 91 - return exar_set_direction(chip, 0, offset); 136 + regmap_clear_bits(exar_gpio->regmap, addr, BIT(bit)); 137 + 138 + return 0; 92 139 } 93 140 94 141 static int exar_direction_input(struct gpio_chip *chip, unsigned int offset) 95 142 { 96 - return exar_set_direction(chip, 1, offset); 143 + struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip); 144 + unsigned int addr = exar_offset_to_sel_addr(exar_gpio, offset); 145 + unsigned int bit = exar_offset_to_bit(exar_gpio, offset); 146 + 147 + regmap_set_bits(exar_gpio->regmap, addr, BIT(bit)); 148 + 149 + return 0; 97 150 } 151 + 152 + static const struct regmap_config exar_regmap_config = { 153 + .name = "exar-gpio", 154 + .reg_bits = 16, 155 + .val_bits = 8, 156 + }; 98 157 99 158 static int gpio_exar_probe(struct platform_device *pdev) 100 159 { ··· 146 163 if (!exar_gpio) 147 164 return -ENOMEM; 148 165 149 - mutex_init(&exar_gpio->lock); 166 + /* 167 + * We don't need to check the return values of mmio regmap operations (unless 168 + * the regmap has a clock attached which is not the case here). 169 + */ 170 + exar_gpio->regmap = devm_regmap_init_mmio(dev, p, &exar_regmap_config); 171 + if (IS_ERR(exar_gpio->regmap)) 172 + return PTR_ERR(exar_gpio->regmap); 150 173 151 174 index = ida_alloc(&ida_index, GFP_KERNEL); 152 - if (index < 0) { 153 - ret = index; 154 - goto err_mutex_destroy; 155 - } 175 + if (index < 0) 176 + return index; 156 177 157 178 sprintf(exar_gpio->name, "exar_gpio%d", index); 158 179 exar_gpio->gpio_chip.label = exar_gpio->name; ··· 168 181 exar_gpio->gpio_chip.set = exar_set_value; 169 182 exar_gpio->gpio_chip.base = -1; 170 183 exar_gpio->gpio_chip.ngpio = ngpios; 171 - exar_gpio->regs = p; 172 184 exar_gpio->index = index; 173 185 exar_gpio->first_pin = first_pin; 174 186 ··· 181 195 182 196 err_destroy: 183 197 ida_free(&ida_index, index); 184 - err_mutex_destroy: 185 - mutex_destroy(&exar_gpio->lock); 186 198 return ret; 187 199 } 188 200 ··· 189 205 struct exar_gpio_chip *exar_gpio = platform_get_drvdata(pdev); 190 206 191 207 ida_free(&ida_index, exar_gpio->index); 192 - mutex_destroy(&exar_gpio->lock); 193 208 194 209 return 0; 195 210 }