diff options
| -rw-r--r-- | drivers/pinctrl/Kconfig | 12 | ||||
| -rw-r--r-- | drivers/pinctrl/Makefile | 1 | ||||
| -rw-r--r-- | drivers/pinctrl/pinctrl-baytrail.c | 543 |
3 files changed, 556 insertions, 0 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 269c0406dce4..e01976fb1175 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
| @@ -58,6 +58,18 @@ config PINCTRL_AT91 | |||
| 58 | help | 58 | help |
| 59 | Say Y here to enable the at91 pinctrl driver | 59 | Say Y here to enable the at91 pinctrl driver |
| 60 | 60 | ||
| 61 | config PINCTRL_BAYTRAIL | ||
| 62 | bool "Intel Baytrail GPIO pin control" | ||
| 63 | depends on GPIOLIB && ACPI && X86 | ||
| 64 | select IRQ_DOMAIN | ||
| 65 | help | ||
| 66 | driver for memory mapped GPIO functionality on Intel Baytrail | ||
| 67 | platforms. Supports 3 banks with 102, 28 and 44 gpios. | ||
| 68 | Most pins are usually muxed to some other functionality by firmware, | ||
| 69 | so only a small amount is available for gpio use. | ||
| 70 | |||
| 71 | Requires ACPI device enumeration code to set up a platform device. | ||
| 72 | |||
| 61 | config PINCTRL_BCM2835 | 73 | config PINCTRL_BCM2835 |
| 62 | bool | 74 | bool |
| 63 | select PINMUX | 75 | select PINMUX |
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index ff38aca65689..9031afddb9ad 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile | |||
| @@ -16,6 +16,7 @@ obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o | |||
| 16 | obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o | 16 | obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o |
| 17 | obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o | 17 | obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o |
| 18 | obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o | 18 | obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o |
| 19 | obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o | ||
| 19 | obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o | 20 | obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o |
| 20 | obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o | 21 | obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o |
| 21 | obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o | 22 | obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o |
diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c new file mode 100644 index 000000000000..e9d735dcebfb --- /dev/null +++ b/drivers/pinctrl/pinctrl-baytrail.c | |||
| @@ -0,0 +1,543 @@ | |||
| 1 | /* | ||
| 2 | * Pinctrl GPIO driver for Intel Baytrail | ||
| 3 | * Copyright (c) 2012-2013, Intel Corporation. | ||
| 4 | * | ||
| 5 | * Author: Mathias Nyman <mathias.nyman@linux.intel.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms and conditions of the GNU General Public License, | ||
| 9 | * version 2, as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 14 | * more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License along with | ||
| 17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/types.h> | ||
| 26 | #include <linux/bitops.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/irq.h> | ||
| 29 | #include <linux/gpio.h> | ||
| 30 | #include <linux/irqdomain.h> | ||
| 31 | #include <linux/acpi.h> | ||
| 32 | #include <linux/acpi_gpio.h> | ||
| 33 | #include <linux/platform_device.h> | ||
| 34 | #include <linux/seq_file.h> | ||
| 35 | #include <linux/io.h> | ||
| 36 | #include <linux/pm_runtime.h> | ||
| 37 | #include <linux/pinctrl/pinctrl.h> | ||
| 38 | |||
| 39 | /* memory mapped register offsets */ | ||
| 40 | #define BYT_CONF0_REG 0x000 | ||
| 41 | #define BYT_CONF1_REG 0x004 | ||
| 42 | #define BYT_VAL_REG 0x008 | ||
| 43 | #define BYT_DFT_REG 0x00c | ||
| 44 | #define BYT_INT_STAT_REG 0x800 | ||
| 45 | |||
| 46 | /* BYT_CONF0_REG register bits */ | ||
| 47 | #define BYT_TRIG_NEG BIT(26) | ||
| 48 | #define BYT_TRIG_POS BIT(25) | ||
| 49 | #define BYT_TRIG_LVL BIT(24) | ||
| 50 | #define BYT_PIN_MUX 0x07 | ||
| 51 | |||
| 52 | /* BYT_VAL_REG register bits */ | ||
| 53 | #define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/ | ||
| 54 | #define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/ | ||
| 55 | #define BYT_LEVEL BIT(0) | ||
| 56 | |||
| 57 | #define BYT_DIR_MASK (BIT(1) | BIT(2)) | ||
| 58 | #define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24)) | ||
| 59 | |||
| 60 | #define BYT_NGPIO_SCORE 102 | ||
| 61 | #define BYT_NGPIO_NCORE 28 | ||
| 62 | #define BYT_NGPIO_SUS 44 | ||
| 63 | |||
| 64 | /* | ||
| 65 | * Baytrail gpio controller consist of three separate sub-controllers called | ||
| 66 | * SCORE, NCORE and SUS. The sub-controllers are identified by their acpi UID. | ||
| 67 | * | ||
| 68 | * GPIO numbering is _not_ ordered meaning that gpio # 0 in ACPI namespace does | ||
| 69 | * _not_ correspond to the first gpio register at controller's gpio base. | ||
| 70 | * There is no logic or pattern in mapping gpio numbers to registers (pads) so | ||
| 71 | * each sub-controller needs to have its own mapping table | ||
| 72 | */ | ||
| 73 | |||
| 74 | /* score_pins[gpio_nr] = pad_nr */ | ||
| 75 | |||
| 76 | static unsigned const score_pins[BYT_NGPIO_SCORE] = { | ||
| 77 | 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, | ||
| 78 | 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, | ||
| 79 | 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, | ||
| 80 | 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, | ||
| 81 | 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, | ||
| 82 | 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, | ||
| 83 | 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, | ||
| 84 | 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, | ||
| 85 | 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, | ||
| 86 | 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, | ||
| 87 | 97, 100, | ||
| 88 | }; | ||
| 89 | |||
| 90 | static unsigned const ncore_pins[BYT_NGPIO_NCORE] = { | ||
| 91 | 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, | ||
| 92 | 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, | ||
| 93 | 3, 6, 10, 13, 2, 5, 9, 7, | ||
| 94 | }; | ||
| 95 | |||
| 96 | static unsigned const sus_pins[BYT_NGPIO_SUS] = { | ||
| 97 | 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, | ||
| 98 | 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, | ||
| 99 | 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, | ||
| 100 | 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, | ||
| 101 | 52, 53, 59, 40, | ||
| 102 | }; | ||
| 103 | |||
| 104 | static struct pinctrl_gpio_range byt_ranges[] = { | ||
| 105 | { | ||
| 106 | .name = "1", /* match with acpi _UID in probe */ | ||
| 107 | .npins = BYT_NGPIO_SCORE, | ||
| 108 | .pins = score_pins, | ||
| 109 | }, | ||
| 110 | { | ||
| 111 | .name = "2", | ||
| 112 | .npins = BYT_NGPIO_NCORE, | ||
| 113 | .pins = ncore_pins, | ||
| 114 | }, | ||
| 115 | { | ||
| 116 | .name = "3", | ||
| 117 | .npins = BYT_NGPIO_SUS, | ||
| 118 | .pins = sus_pins, | ||
| 119 | }, | ||
| 120 | { | ||
| 121 | }, | ||
| 122 | }; | ||
| 123 | |||
| 124 | struct byt_gpio { | ||
| 125 | struct gpio_chip chip; | ||
| 126 | struct irq_domain *domain; | ||
| 127 | struct platform_device *pdev; | ||
| 128 | spinlock_t lock; | ||
| 129 | void __iomem *reg_base; | ||
| 130 | struct pinctrl_gpio_range *range; | ||
| 131 | }; | ||
| 132 | |||
| 133 | static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset, | ||
| 134 | int reg) | ||
| 135 | { | ||
| 136 | struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip); | ||
| 137 | u32 reg_offset; | ||
| 138 | void __iomem *ptr; | ||
| 139 | |||
| 140 | if (reg == BYT_INT_STAT_REG) | ||
| 141 | reg_offset = (offset / 32) * 4; | ||
| 142 | else | ||
| 143 | reg_offset = vg->range->pins[offset] * 16; | ||
| 144 | |||
| 145 | ptr = (void __iomem *) (vg->reg_base + reg_offset + reg); | ||
| 146 | return ptr; | ||
| 147 | } | ||
| 148 | |||
| 149 | static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
| 150 | { | ||
| 151 | struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip); | ||
| 152 | |||
| 153 | pm_runtime_get(&vg->pdev->dev); | ||
| 154 | |||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | |||
| 158 | static void byt_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
| 159 | { | ||
| 160 | struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip); | ||
| 161 | void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); | ||
| 162 | u32 value; | ||
| 163 | |||
| 164 | /* clear interrupt triggering */ | ||
| 165 | value = readl(reg); | ||
| 166 | value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); | ||
| 167 | writel(value, reg); | ||
| 168 | |||
| 169 | pm_runtime_put(&vg->pdev->dev); | ||
| 170 | } | ||
| 171 | |||
| 172 | static int byt_irq_type(struct irq_data *d, unsigned type) | ||
| 173 | { | ||
| 174 | struct byt_gpio *vg = irq_data_get_irq_chip_data(d); | ||
| 175 | u32 offset = irqd_to_hwirq(d); | ||
| 176 | u32 value; | ||
| 177 | unsigned long flags; | ||
| 178 | void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); | ||
| 179 | |||
| 180 | if (offset >= vg->chip.ngpio) | ||
| 181 | return -EINVAL; | ||
| 182 | |||
| 183 | spin_lock_irqsave(&vg->lock, flags); | ||
| 184 | value = readl(reg); | ||
| 185 | |||
| 186 | /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits | ||
| 187 | * are used to indicate high and low level triggering | ||
| 188 | */ | ||
| 189 | value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); | ||
| 190 | |||
| 191 | switch (type) { | ||
| 192 | case IRQ_TYPE_LEVEL_HIGH: | ||
| 193 | value |= BYT_TRIG_LVL; | ||
| 194 | case IRQ_TYPE_EDGE_RISING: | ||
| 195 | value |= BYT_TRIG_POS; | ||
| 196 | break; | ||
| 197 | case IRQ_TYPE_LEVEL_LOW: | ||
| 198 | value |= BYT_TRIG_LVL; | ||
| 199 | case IRQ_TYPE_EDGE_FALLING: | ||
| 200 | value |= BYT_TRIG_NEG; | ||
| 201 | break; | ||
| 202 | case IRQ_TYPE_EDGE_BOTH: | ||
| 203 | value |= (BYT_TRIG_NEG | BYT_TRIG_POS); | ||
| 204 | break; | ||
| 205 | } | ||
| 206 | writel(value, reg); | ||
| 207 | |||
| 208 | spin_unlock_irqrestore(&vg->lock, flags); | ||
| 209 | |||
| 210 | return 0; | ||
| 211 | } | ||
| 212 | |||
| 213 | static int byt_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 214 | { | ||
| 215 | void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG); | ||
| 216 | return readl(reg) & BYT_LEVEL; | ||
| 217 | } | ||
| 218 | |||
| 219 | static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 220 | { | ||
| 221 | struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip); | ||
| 222 | void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG); | ||
| 223 | unsigned long flags; | ||
| 224 | u32 old_val; | ||
| 225 | |||
| 226 | spin_lock_irqsave(&vg->lock, flags); | ||
| 227 | |||
| 228 | old_val = readl(reg); | ||
| 229 | |||
| 230 | if (value) | ||
| 231 | writel(old_val | BYT_LEVEL, reg); | ||
| 232 | else | ||
| 233 | writel(old_val & ~BYT_LEVEL, reg); | ||
| 234 | |||
| 235 | spin_unlock_irqrestore(&vg->lock, flags); | ||
| 236 | } | ||
| 237 | |||
| 238 | static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 239 | { | ||
| 240 | struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip); | ||
| 241 | void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG); | ||
| 242 | unsigned long flags; | ||
| 243 | u32 value; | ||
| 244 | |||
| 245 | spin_lock_irqsave(&vg->lock, flags); | ||
| 246 | |||
| 247 | value = readl(reg) | BYT_DIR_MASK; | ||
| 248 | value = value & (~BYT_INPUT_EN); /* active low */ | ||
| 249 | writel(value, reg); | ||
| 250 | |||
| 251 | spin_unlock_irqrestore(&vg->lock, flags); | ||
| 252 | |||
| 253 | return 0; | ||
| 254 | } | ||
| 255 | |||
| 256 | static int byt_gpio_direction_output(struct gpio_chip *chip, | ||
| 257 | unsigned gpio, int value) | ||
| 258 | { | ||
| 259 | struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip); | ||
| 260 | void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG); | ||
| 261 | unsigned long flags; | ||
| 262 | u32 reg_val; | ||
| 263 | |||
| 264 | spin_lock_irqsave(&vg->lock, flags); | ||
| 265 | |||
| 266 | reg_val = readl(reg) | (BYT_DIR_MASK | !!value); | ||
| 267 | reg_val &= ~(BYT_OUTPUT_EN | !value); | ||
| 268 | writel(reg_val, reg); | ||
| 269 | |||
| 270 | spin_unlock_irqrestore(&vg->lock, flags); | ||
| 271 | |||
| 272 | return 0; | ||
| 273 | } | ||
| 274 | |||
| 275 | static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | ||
| 276 | { | ||
| 277 | struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip); | ||
| 278 | int i; | ||
| 279 | unsigned long flags; | ||
| 280 | u32 conf0, val, offs; | ||
| 281 | |||
| 282 | spin_lock_irqsave(&vg->lock, flags); | ||
| 283 | |||
| 284 | for (i = 0; i < vg->chip.ngpio; i++) { | ||
| 285 | offs = vg->range->pins[i] * 16; | ||
| 286 | conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG); | ||
| 287 | val = readl(vg->reg_base + offs + BYT_VAL_REG); | ||
| 288 | |||
| 289 | seq_printf(s, | ||
| 290 | " gpio-%-3d %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s\n", | ||
| 291 | i, | ||
| 292 | val & BYT_INPUT_EN ? " " : "in", | ||
| 293 | val & BYT_OUTPUT_EN ? " " : "out", | ||
| 294 | val & BYT_LEVEL ? "hi" : "lo", | ||
| 295 | vg->range->pins[i], offs, | ||
| 296 | conf0 & 0x7, | ||
| 297 | conf0 & BYT_TRIG_NEG ? "fall " : "", | ||
| 298 | conf0 & BYT_TRIG_POS ? "rise " : "", | ||
| 299 | conf0 & BYT_TRIG_LVL ? "lvl " : ""); | ||
| 300 | } | ||
| 301 | spin_unlock_irqrestore(&vg->lock, flags); | ||
| 302 | } | ||
| 303 | |||
| 304 | static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
| 305 | { | ||
| 306 | struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip); | ||
| 307 | return irq_create_mapping(vg->domain, offset); | ||
| 308 | } | ||
| 309 | |||
| 310 | static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
| 311 | { | ||
| 312 | struct irq_data *data = irq_desc_get_irq_data(desc); | ||
| 313 | struct byt_gpio *vg = irq_data_get_irq_handler_data(data); | ||
| 314 | struct irq_chip *chip = irq_data_get_irq_chip(data); | ||
| 315 | u32 base, pin, mask; | ||
| 316 | void __iomem *reg; | ||
| 317 | u32 pending; | ||
| 318 | unsigned virq; | ||
| 319 | int looplimit = 0; | ||
| 320 | |||
| 321 | /* check from GPIO controller which pin triggered the interrupt */ | ||
| 322 | for (base = 0; base < vg->chip.ngpio; base += 32) { | ||
| 323 | |||
| 324 | reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG); | ||
| 325 | |||
| 326 | while ((pending = readl(reg))) { | ||
| 327 | pin = __ffs(pending); | ||
| 328 | mask = BIT(pin); | ||
| 329 | /* Clear before handling so we can't lose an edge */ | ||
| 330 | writel(mask, reg); | ||
| 331 | |||
| 332 | virq = irq_find_mapping(vg->domain, base + pin); | ||
| 333 | generic_handle_irq(virq); | ||
| 334 | |||
| 335 | /* In case bios or user sets triggering incorretly a pin | ||
| 336 | * might remain in "interrupt triggered" state. | ||
| 337 | */ | ||
| 338 | if (looplimit++ > 32) { | ||
| 339 | dev_err(&vg->pdev->dev, | ||
| 340 | "Gpio %d interrupt flood, disabling\n", | ||
| 341 | base + pin); | ||
| 342 | |||
| 343 | reg = byt_gpio_reg(&vg->chip, base + pin, | ||
| 344 | BYT_CONF0_REG); | ||
| 345 | mask = readl(reg); | ||
| 346 | mask &= ~(BYT_TRIG_NEG | BYT_TRIG_POS | | ||
| 347 | BYT_TRIG_LVL); | ||
| 348 | writel(mask, reg); | ||
| 349 | mask = readl(reg); /* flush */ | ||
| 350 | break; | ||
| 351 | } | ||
| 352 | } | ||
| 353 | } | ||
| 354 | chip->irq_eoi(data); | ||
| 355 | } | ||
| 356 | |||
| 357 | static void byt_irq_unmask(struct irq_data *d) | ||
| 358 | { | ||
| 359 | } | ||
| 360 | |||
| 361 | static void byt_irq_mask(struct irq_data *d) | ||
| 362 | { | ||
| 363 | } | ||
| 364 | |||
| 365 | static struct irq_chip byt_irqchip = { | ||
| 366 | .name = "BYT-GPIO", | ||
| 367 | .irq_mask = byt_irq_mask, | ||
| 368 | .irq_unmask = byt_irq_unmask, | ||
| 369 | .irq_set_type = byt_irq_type, | ||
| 370 | }; | ||
| 371 | |||
| 372 | static void byt_gpio_irq_init_hw(struct byt_gpio *vg) | ||
| 373 | { | ||
| 374 | void __iomem *reg; | ||
| 375 | u32 base, value; | ||
| 376 | |||
| 377 | /* clear interrupt status trigger registers */ | ||
| 378 | for (base = 0; base < vg->chip.ngpio; base += 32) { | ||
| 379 | reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG); | ||
| 380 | writel(0xffffffff, reg); | ||
| 381 | /* make sure trigger bits are cleared, if not then a pin | ||
| 382 | might be misconfigured in bios */ | ||
| 383 | value = readl(reg); | ||
| 384 | if (value) | ||
| 385 | dev_err(&vg->pdev->dev, | ||
| 386 | "GPIO interrupt error, pins misconfigured\n"); | ||
| 387 | } | ||
| 388 | } | ||
| 389 | |||
| 390 | static int byt_gpio_irq_map(struct irq_domain *d, unsigned int virq, | ||
| 391 | irq_hw_number_t hw) | ||
| 392 | { | ||
| 393 | struct byt_gpio *vg = d->host_data; | ||
| 394 | |||
| 395 | irq_set_chip_and_handler_name(virq, &byt_irqchip, handle_simple_irq, | ||
| 396 | "demux"); | ||
| 397 | irq_set_chip_data(virq, vg); | ||
| 398 | irq_set_irq_type(virq, IRQ_TYPE_NONE); | ||
| 399 | |||
| 400 | return 0; | ||
| 401 | } | ||
| 402 | |||
| 403 | static const struct irq_domain_ops byt_gpio_irq_ops = { | ||
| 404 | .map = byt_gpio_irq_map, | ||
| 405 | }; | ||
| 406 | |||
| 407 | static int byt_gpio_probe(struct platform_device *pdev) | ||
| 408 | { | ||
| 409 | struct byt_gpio *vg; | ||
| 410 | struct gpio_chip *gc; | ||
| 411 | struct resource *mem_rc, *irq_rc; | ||
| 412 | struct device *dev = &pdev->dev; | ||
| 413 | struct acpi_device *acpi_dev; | ||
| 414 | struct pinctrl_gpio_range *range; | ||
| 415 | acpi_handle handle = ACPI_HANDLE(dev); | ||
| 416 | unsigned hwirq; | ||
| 417 | int ret; | ||
| 418 | |||
| 419 | if (acpi_bus_get_device(handle, &acpi_dev)) | ||
| 420 | return -ENODEV; | ||
| 421 | |||
| 422 | vg = devm_kzalloc(dev, sizeof(struct byt_gpio), GFP_KERNEL); | ||
| 423 | if (!vg) { | ||
| 424 | dev_err(&pdev->dev, "can't allocate byt_gpio chip data\n"); | ||
| 425 | return -ENOMEM; | ||
| 426 | } | ||
| 427 | |||
| 428 | for (range = byt_ranges; range->name; range++) { | ||
| 429 | if (!strcmp(acpi_dev->pnp.unique_id, range->name)) { | ||
| 430 | vg->chip.ngpio = range->npins; | ||
| 431 | vg->range = range; | ||
| 432 | break; | ||
| 433 | } | ||
| 434 | } | ||
| 435 | |||
| 436 | if (!vg->chip.ngpio || !vg->range) | ||
| 437 | return -ENODEV; | ||
| 438 | |||
| 439 | vg->pdev = pdev; | ||
| 440 | platform_set_drvdata(pdev, vg); | ||
| 441 | |||
| 442 | mem_rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 443 | vg->reg_base = devm_ioremap_resource(dev, mem_rc); | ||
| 444 | if (IS_ERR(vg->reg_base)) | ||
| 445 | return PTR_ERR(vg->reg_base); | ||
| 446 | |||
| 447 | spin_lock_init(&vg->lock); | ||
| 448 | |||
| 449 | gc = &vg->chip; | ||
| 450 | gc->label = dev_name(&pdev->dev); | ||
| 451 | gc->owner = THIS_MODULE; | ||
| 452 | gc->request = byt_gpio_request; | ||
| 453 | gc->free = byt_gpio_free; | ||
| 454 | gc->direction_input = byt_gpio_direction_input; | ||
| 455 | gc->direction_output = byt_gpio_direction_output; | ||
| 456 | gc->get = byt_gpio_get; | ||
| 457 | gc->set = byt_gpio_set; | ||
| 458 | gc->dbg_show = byt_gpio_dbg_show; | ||
| 459 | gc->base = -1; | ||
| 460 | gc->can_sleep = 0; | ||
| 461 | gc->dev = dev; | ||
| 462 | |||
| 463 | ret = gpiochip_add(gc); | ||
| 464 | if (ret) { | ||
| 465 | dev_err(&pdev->dev, "failed adding byt-gpio chip\n"); | ||
| 466 | return ret; | ||
| 467 | } | ||
| 468 | |||
| 469 | /* set up interrupts */ | ||
| 470 | irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 471 | if (irq_rc && irq_rc->start) { | ||
| 472 | hwirq = irq_rc->start; | ||
| 473 | gc->to_irq = byt_gpio_to_irq; | ||
| 474 | |||
| 475 | vg->domain = irq_domain_add_linear(NULL, gc->ngpio, | ||
| 476 | &byt_gpio_irq_ops, vg); | ||
| 477 | if (!vg->domain) | ||
| 478 | return -ENXIO; | ||
| 479 | |||
| 480 | byt_gpio_irq_init_hw(vg); | ||
| 481 | |||
| 482 | irq_set_handler_data(hwirq, vg); | ||
| 483 | irq_set_chained_handler(hwirq, byt_gpio_irq_handler); | ||
| 484 | |||
| 485 | /* Register interrupt handlers for gpio signaled acpi events */ | ||
| 486 | acpi_gpiochip_request_interrupts(gc); | ||
| 487 | } | ||
| 488 | |||
| 489 | pm_runtime_enable(dev); | ||
| 490 | |||
| 491 | return 0; | ||
| 492 | } | ||
| 493 | |||
| 494 | static int byt_gpio_runtime_suspend(struct device *dev) | ||
| 495 | { | ||
| 496 | return 0; | ||
| 497 | } | ||
| 498 | |||
| 499 | static int byt_gpio_runtime_resume(struct device *dev) | ||
| 500 | { | ||
| 501 | return 0; | ||
| 502 | } | ||
| 503 | |||
| 504 | static const struct dev_pm_ops byt_gpio_pm_ops = { | ||
| 505 | .runtime_suspend = byt_gpio_runtime_suspend, | ||
| 506 | .runtime_resume = byt_gpio_runtime_resume, | ||
| 507 | }; | ||
| 508 | |||
| 509 | static const struct acpi_device_id byt_gpio_acpi_match[] = { | ||
| 510 | { "INT33B2", 0 }, | ||
| 511 | { } | ||
| 512 | }; | ||
| 513 | MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); | ||
| 514 | |||
| 515 | static int byt_gpio_remove(struct platform_device *pdev) | ||
| 516 | { | ||
| 517 | struct byt_gpio *vg = platform_get_drvdata(pdev); | ||
| 518 | int err; | ||
| 519 | pm_runtime_disable(&pdev->dev); | ||
| 520 | err = gpiochip_remove(&vg->chip); | ||
| 521 | if (err) | ||
| 522 | dev_warn(&pdev->dev, "failed to remove gpio_chip.\n"); | ||
| 523 | |||
| 524 | return 0; | ||
| 525 | } | ||
| 526 | |||
| 527 | static struct platform_driver byt_gpio_driver = { | ||
| 528 | .probe = byt_gpio_probe, | ||
| 529 | .remove = byt_gpio_remove, | ||
| 530 | .driver = { | ||
| 531 | .name = "byt_gpio", | ||
| 532 | .owner = THIS_MODULE, | ||
| 533 | .pm = &byt_gpio_pm_ops, | ||
| 534 | .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match), | ||
| 535 | }, | ||
| 536 | }; | ||
| 537 | |||
| 538 | static int __init byt_gpio_init(void) | ||
| 539 | { | ||
| 540 | return platform_driver_register(&byt_gpio_driver); | ||
| 541 | } | ||
| 542 | |||
| 543 | subsys_initcall(byt_gpio_init); | ||
