diff options
Diffstat (limited to 'drivers/gpio')
| -rw-r--r-- | drivers/gpio/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/gpio/gpio-adp5588.c | 2 | ||||
| -rw-r--r-- | drivers/gpio/gpio-omap.c | 9 | ||||
| -rw-r--r-- | drivers/gpio/gpio-pch.c | 57 | ||||
| -rw-r--r-- | drivers/gpio/gpio-pxa.c | 21 | ||||
| -rw-r--r-- | drivers/gpio/gpio-samsung.c | 34 | ||||
| -rw-r--r-- | drivers/gpio/gpio-sodaville.c | 23 | ||||
| -rw-r--r-- | drivers/gpio/gpio-tegra.c | 59 |
8 files changed, 126 insertions, 81 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index edadbdad31d0..e03653d69357 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
| @@ -430,7 +430,7 @@ config GPIO_ML_IOH | |||
| 430 | 430 | ||
| 431 | config GPIO_SODAVILLE | 431 | config GPIO_SODAVILLE |
| 432 | bool "Intel Sodaville GPIO support" | 432 | bool "Intel Sodaville GPIO support" |
| 433 | depends on X86 && PCI && OF && BROKEN | 433 | depends on X86 && PCI && OF |
| 434 | select GPIO_GENERIC | 434 | select GPIO_GENERIC |
| 435 | select GENERIC_IRQ_CHIP | 435 | select GENERIC_IRQ_CHIP |
| 436 | help | 436 | help |
diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c index 9ad1703d1408..ae5d7f12ce66 100644 --- a/drivers/gpio/gpio-adp5588.c +++ b/drivers/gpio/gpio-adp5588.c | |||
| @@ -252,7 +252,7 @@ static irqreturn_t adp5588_irq_handler(int irq, void *devid) | |||
| 252 | if (ret < 0) | 252 | if (ret < 0) |
| 253 | memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat)); | 253 | memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat)); |
| 254 | 254 | ||
| 255 | for (bank = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO); | 255 | for (bank = 0, bit = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO); |
| 256 | bank++, bit = 0) { | 256 | bank++, bit = 0) { |
| 257 | pending = dev->irq_stat[bank] & dev->irq_mask[bank]; | 257 | pending = dev->irq_stat[bank] & dev->irq_mask[bank]; |
| 258 | 258 | ||
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 1adc2ec1e383..4461540653a8 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -965,18 +965,15 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) | |||
| 965 | } | 965 | } |
| 966 | 966 | ||
| 967 | _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv); | 967 | _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv); |
| 968 | _gpio_rmw(base, bank->regs->irqstatus, l, | 968 | _gpio_rmw(base, bank->regs->irqstatus, l, !bank->regs->irqenable_inv); |
| 969 | bank->regs->irqenable_inv == false); | ||
| 970 | _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0); | ||
| 971 | _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0); | ||
| 972 | if (bank->regs->debounce_en) | 969 | if (bank->regs->debounce_en) |
| 973 | _gpio_rmw(base, bank->regs->debounce_en, 0, 1); | 970 | __raw_writel(0, base + bank->regs->debounce_en); |
| 974 | 971 | ||
| 975 | /* Save OE default value (0xffffffff) in the context */ | 972 | /* Save OE default value (0xffffffff) in the context */ |
| 976 | bank->context.oe = __raw_readl(bank->base + bank->regs->direction); | 973 | bank->context.oe = __raw_readl(bank->base + bank->regs->direction); |
| 977 | /* Initialize interface clk ungated, module enabled */ | 974 | /* Initialize interface clk ungated, module enabled */ |
| 978 | if (bank->regs->ctrl) | 975 | if (bank->regs->ctrl) |
| 979 | _gpio_rmw(base, bank->regs->ctrl, 0, 1); | 976 | __raw_writel(0, base + bank->regs->ctrl); |
| 980 | } | 977 | } |
| 981 | 978 | ||
| 982 | static __devinit void | 979 | static __devinit void |
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index e8729cc2ba2b..2cd958e0b822 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c | |||
| @@ -230,16 +230,12 @@ static void pch_gpio_setup(struct pch_gpio *chip) | |||
| 230 | 230 | ||
| 231 | static int pch_irq_type(struct irq_data *d, unsigned int type) | 231 | static int pch_irq_type(struct irq_data *d, unsigned int type) |
| 232 | { | 232 | { |
| 233 | u32 im; | ||
| 234 | u32 __iomem *im_reg; | ||
| 235 | u32 ien; | ||
| 236 | u32 im_pos; | ||
| 237 | int ch; | ||
| 238 | unsigned long flags; | ||
| 239 | u32 val; | ||
| 240 | int irq = d->irq; | ||
| 241 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 233 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
| 242 | struct pch_gpio *chip = gc->private; | 234 | struct pch_gpio *chip = gc->private; |
| 235 | u32 im, im_pos, val; | ||
| 236 | u32 __iomem *im_reg; | ||
| 237 | unsigned long flags; | ||
| 238 | int ch, irq = d->irq; | ||
| 243 | 239 | ||
| 244 | ch = irq - chip->irq_base; | 240 | ch = irq - chip->irq_base; |
| 245 | if (irq <= chip->irq_base + 7) { | 241 | if (irq <= chip->irq_base + 7) { |
| @@ -270,30 +266,22 @@ static int pch_irq_type(struct irq_data *d, unsigned int type) | |||
| 270 | case IRQ_TYPE_LEVEL_LOW: | 266 | case IRQ_TYPE_LEVEL_LOW: |
| 271 | val = PCH_LEVEL_L; | 267 | val = PCH_LEVEL_L; |
| 272 | break; | 268 | break; |
| 273 | case IRQ_TYPE_PROBE: | ||
| 274 | goto end; | ||
| 275 | default: | 269 | default: |
| 276 | dev_warn(chip->dev, "%s: unknown type(%dd)", | 270 | goto unlock; |
| 277 | __func__, type); | ||
| 278 | goto end; | ||
| 279 | } | 271 | } |
| 280 | 272 | ||
| 281 | /* Set interrupt mode */ | 273 | /* Set interrupt mode */ |
| 282 | im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); | 274 | im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); |
| 283 | iowrite32(im | (val << (im_pos * 4)), im_reg); | 275 | iowrite32(im | (val << (im_pos * 4)), im_reg); |
| 284 | 276 | ||
| 285 | /* iclr */ | 277 | /* And the handler */ |
| 286 | iowrite32(BIT(ch), &chip->reg->iclr); | 278 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
| 279 | __irq_set_handler_locked(d->irq, handle_level_irq); | ||
| 280 | else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | ||
| 281 | __irq_set_handler_locked(d->irq, handle_edge_irq); | ||
| 287 | 282 | ||
| 288 | /* IMASKCLR */ | 283 | unlock: |
| 289 | iowrite32(BIT(ch), &chip->reg->imaskclr); | ||
| 290 | |||
| 291 | /* Enable interrupt */ | ||
| 292 | ien = ioread32(&chip->reg->ien); | ||
| 293 | iowrite32(ien | BIT(ch), &chip->reg->ien); | ||
| 294 | end: | ||
| 295 | spin_unlock_irqrestore(&chip->spinlock, flags); | 284 | spin_unlock_irqrestore(&chip->spinlock, flags); |
| 296 | |||
| 297 | return 0; | 285 | return 0; |
| 298 | } | 286 | } |
| 299 | 287 | ||
| @@ -313,18 +301,24 @@ static void pch_irq_mask(struct irq_data *d) | |||
| 313 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); | 301 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); |
| 314 | } | 302 | } |
| 315 | 303 | ||
| 304 | static void pch_irq_ack(struct irq_data *d) | ||
| 305 | { | ||
| 306 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
| 307 | struct pch_gpio *chip = gc->private; | ||
| 308 | |||
| 309 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->iclr); | ||
| 310 | } | ||
| 311 | |||
| 316 | static irqreturn_t pch_gpio_handler(int irq, void *dev_id) | 312 | static irqreturn_t pch_gpio_handler(int irq, void *dev_id) |
| 317 | { | 313 | { |
| 318 | struct pch_gpio *chip = dev_id; | 314 | struct pch_gpio *chip = dev_id; |
| 319 | u32 reg_val = ioread32(&chip->reg->istatus); | 315 | u32 reg_val = ioread32(&chip->reg->istatus); |
| 320 | int i; | 316 | int i, ret = IRQ_NONE; |
| 321 | int ret = IRQ_NONE; | ||
| 322 | 317 | ||
| 323 | for (i = 0; i < gpio_pins[chip->ioh]; i++) { | 318 | for (i = 0; i < gpio_pins[chip->ioh]; i++) { |
| 324 | if (reg_val & BIT(i)) { | 319 | if (reg_val & BIT(i)) { |
| 325 | dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", | 320 | dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", |
| 326 | __func__, i, irq, reg_val); | 321 | __func__, i, irq, reg_val); |
| 327 | iowrite32(BIT(i), &chip->reg->iclr); | ||
| 328 | generic_handle_irq(chip->irq_base + i); | 322 | generic_handle_irq(chip->irq_base + i); |
| 329 | ret = IRQ_HANDLED; | 323 | ret = IRQ_HANDLED; |
| 330 | } | 324 | } |
| @@ -343,6 +337,7 @@ static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, | |||
| 343 | gc->private = chip; | 337 | gc->private = chip; |
| 344 | ct = gc->chip_types; | 338 | ct = gc->chip_types; |
| 345 | 339 | ||
| 340 | ct->chip.irq_ack = pch_irq_ack; | ||
| 346 | ct->chip.irq_mask = pch_irq_mask; | 341 | ct->chip.irq_mask = pch_irq_mask; |
| 347 | ct->chip.irq_unmask = pch_irq_unmask; | 342 | ct->chip.irq_unmask = pch_irq_unmask; |
| 348 | ct->chip.irq_set_type = pch_irq_type; | 343 | ct->chip.irq_set_type = pch_irq_type; |
| @@ -357,6 +352,7 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
| 357 | s32 ret; | 352 | s32 ret; |
| 358 | struct pch_gpio *chip; | 353 | struct pch_gpio *chip; |
| 359 | int irq_base; | 354 | int irq_base; |
| 355 | u32 msk; | ||
| 360 | 356 | ||
| 361 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 357 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
| 362 | if (chip == NULL) | 358 | if (chip == NULL) |
| @@ -408,8 +404,13 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
| 408 | } | 404 | } |
| 409 | chip->irq_base = irq_base; | 405 | chip->irq_base = irq_base; |
| 410 | 406 | ||
| 407 | /* Mask all interrupts, but enable them */ | ||
| 408 | msk = (1 << gpio_pins[chip->ioh]) - 1; | ||
| 409 | iowrite32(msk, &chip->reg->imask); | ||
| 410 | iowrite32(msk, &chip->reg->ien); | ||
| 411 | |||
| 411 | ret = request_irq(pdev->irq, pch_gpio_handler, | 412 | ret = request_irq(pdev->irq, pch_gpio_handler, |
| 412 | IRQF_SHARED, KBUILD_MODNAME, chip); | 413 | IRQF_SHARED, KBUILD_MODNAME, chip); |
| 413 | if (ret != 0) { | 414 | if (ret != 0) { |
| 414 | dev_err(&pdev->dev, | 415 | dev_err(&pdev->dev, |
| 415 | "%s request_irq failed\n", __func__); | 416 | "%s request_irq failed\n", __func__); |
| @@ -418,8 +419,6 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
| 418 | 419 | ||
| 419 | pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); | 420 | pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); |
| 420 | 421 | ||
| 421 | /* Initialize interrupt ien register */ | ||
| 422 | iowrite32(0, &chip->reg->ien); | ||
| 423 | end: | 422 | end: |
| 424 | return 0; | 423 | return 0; |
| 425 | 424 | ||
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 5689ce62fd81..fc3ace3fd4cb 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
| @@ -64,6 +64,7 @@ struct pxa_gpio_chip { | |||
| 64 | unsigned long irq_mask; | 64 | unsigned long irq_mask; |
| 65 | unsigned long irq_edge_rise; | 65 | unsigned long irq_edge_rise; |
| 66 | unsigned long irq_edge_fall; | 66 | unsigned long irq_edge_fall; |
| 67 | int (*set_wake)(unsigned int gpio, unsigned int on); | ||
| 67 | 68 | ||
| 68 | #ifdef CONFIG_PM | 69 | #ifdef CONFIG_PM |
| 69 | unsigned long saved_gplr; | 70 | unsigned long saved_gplr; |
| @@ -269,7 +270,8 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
| 269 | (value ? GPSR_OFFSET : GPCR_OFFSET)); | 270 | (value ? GPSR_OFFSET : GPCR_OFFSET)); |
| 270 | } | 271 | } |
| 271 | 272 | ||
| 272 | static int __devinit pxa_init_gpio_chip(int gpio_end) | 273 | static int __devinit pxa_init_gpio_chip(int gpio_end, |
| 274 | int (*set_wake)(unsigned int, unsigned int)) | ||
| 273 | { | 275 | { |
| 274 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; | 276 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; |
| 275 | struct pxa_gpio_chip *chips; | 277 | struct pxa_gpio_chip *chips; |
| @@ -285,6 +287,7 @@ static int __devinit pxa_init_gpio_chip(int gpio_end) | |||
| 285 | 287 | ||
| 286 | sprintf(chips[i].label, "gpio-%d", i); | 288 | sprintf(chips[i].label, "gpio-%d", i); |
| 287 | chips[i].regbase = gpio_reg_base + BANK_OFF(i); | 289 | chips[i].regbase = gpio_reg_base + BANK_OFF(i); |
| 290 | chips[i].set_wake = set_wake; | ||
| 288 | 291 | ||
| 289 | c->base = gpio; | 292 | c->base = gpio; |
| 290 | c->label = chips[i].label; | 293 | c->label = chips[i].label; |
| @@ -412,6 +415,17 @@ static void pxa_mask_muxed_gpio(struct irq_data *d) | |||
| 412 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); | 415 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); |
| 413 | } | 416 | } |
| 414 | 417 | ||
| 418 | static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) | ||
| 419 | { | ||
| 420 | int gpio = pxa_irq_to_gpio(d->irq); | ||
| 421 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | ||
| 422 | |||
| 423 | if (c->set_wake) | ||
| 424 | return c->set_wake(gpio, on); | ||
| 425 | else | ||
| 426 | return 0; | ||
| 427 | } | ||
| 428 | |||
| 415 | static void pxa_unmask_muxed_gpio(struct irq_data *d) | 429 | static void pxa_unmask_muxed_gpio(struct irq_data *d) |
| 416 | { | 430 | { |
| 417 | int gpio = pxa_irq_to_gpio(d->irq); | 431 | int gpio = pxa_irq_to_gpio(d->irq); |
| @@ -427,6 +441,7 @@ static struct irq_chip pxa_muxed_gpio_chip = { | |||
| 427 | .irq_mask = pxa_mask_muxed_gpio, | 441 | .irq_mask = pxa_mask_muxed_gpio, |
| 428 | .irq_unmask = pxa_unmask_muxed_gpio, | 442 | .irq_unmask = pxa_unmask_muxed_gpio, |
| 429 | .irq_set_type = pxa_gpio_irq_type, | 443 | .irq_set_type = pxa_gpio_irq_type, |
| 444 | .irq_set_wake = pxa_gpio_set_wake, | ||
| 430 | }; | 445 | }; |
| 431 | 446 | ||
| 432 | static int pxa_gpio_nums(void) | 447 | static int pxa_gpio_nums(void) |
| @@ -471,6 +486,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) | |||
| 471 | struct pxa_gpio_chip *c; | 486 | struct pxa_gpio_chip *c; |
| 472 | struct resource *res; | 487 | struct resource *res; |
| 473 | struct clk *clk; | 488 | struct clk *clk; |
| 489 | struct pxa_gpio_platform_data *info; | ||
| 474 | int gpio, irq, ret; | 490 | int gpio, irq, ret; |
| 475 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; | 491 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; |
| 476 | 492 | ||
| @@ -516,7 +532,8 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) | |||
| 516 | } | 532 | } |
| 517 | 533 | ||
| 518 | /* Initialize GPIO chips */ | 534 | /* Initialize GPIO chips */ |
| 519 | pxa_init_gpio_chip(pxa_last_gpio); | 535 | info = dev_get_platdata(&pdev->dev); |
| 536 | pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL); | ||
| 520 | 537 | ||
| 521 | /* clear all GPIO edge detects */ | 538 | /* clear all GPIO edge detects */ |
| 522 | for_each_gpio_chip(gpio, c) { | 539 | for_each_gpio_chip(gpio, c) { |
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 46277877b7ec..e991d9171961 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
| @@ -452,12 +452,14 @@ static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = { | |||
| 452 | }; | 452 | }; |
| 453 | #endif | 453 | #endif |
| 454 | 454 | ||
| 455 | #if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5) | ||
| 455 | static struct samsung_gpio_cfg exynos_gpio_cfg = { | 456 | static struct samsung_gpio_cfg exynos_gpio_cfg = { |
| 456 | .set_pull = exynos_gpio_setpull, | 457 | .set_pull = exynos_gpio_setpull, |
| 457 | .get_pull = exynos_gpio_getpull, | 458 | .get_pull = exynos_gpio_getpull, |
| 458 | .set_config = samsung_gpio_setcfg_4bit, | 459 | .set_config = samsung_gpio_setcfg_4bit, |
| 459 | .get_config = samsung_gpio_getcfg_4bit, | 460 | .get_config = samsung_gpio_getcfg_4bit, |
| 460 | }; | 461 | }; |
| 462 | #endif | ||
| 461 | 463 | ||
| 462 | #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) | 464 | #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) |
| 463 | static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = { | 465 | static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = { |
| @@ -2123,8 +2125,8 @@ static struct samsung_gpio_chip s5pv210_gpios_4bit[] = { | |||
| 2123 | * uses the above macro and depends on the banks being listed in order here. | 2125 | * uses the above macro and depends on the banks being listed in order here. |
| 2124 | */ | 2126 | */ |
| 2125 | 2127 | ||
| 2126 | static struct samsung_gpio_chip exynos4_gpios_1[] = { | ||
| 2127 | #ifdef CONFIG_ARCH_EXYNOS4 | 2128 | #ifdef CONFIG_ARCH_EXYNOS4 |
| 2129 | static struct samsung_gpio_chip exynos4_gpios_1[] = { | ||
| 2128 | { | 2130 | { |
| 2129 | .chip = { | 2131 | .chip = { |
| 2130 | .base = EXYNOS4_GPA0(0), | 2132 | .base = EXYNOS4_GPA0(0), |
| @@ -2222,11 +2224,11 @@ static struct samsung_gpio_chip exynos4_gpios_1[] = { | |||
| 2222 | .label = "GPF3", | 2224 | .label = "GPF3", |
| 2223 | }, | 2225 | }, |
| 2224 | }, | 2226 | }, |
| 2225 | #endif | ||
| 2226 | }; | 2227 | }; |
| 2228 | #endif | ||
| 2227 | 2229 | ||
| 2228 | static struct samsung_gpio_chip exynos4_gpios_2[] = { | ||
| 2229 | #ifdef CONFIG_ARCH_EXYNOS4 | 2230 | #ifdef CONFIG_ARCH_EXYNOS4 |
| 2231 | static struct samsung_gpio_chip exynos4_gpios_2[] = { | ||
| 2230 | { | 2232 | { |
| 2231 | .chip = { | 2233 | .chip = { |
| 2232 | .base = EXYNOS4_GPJ0(0), | 2234 | .base = EXYNOS4_GPJ0(0), |
| @@ -2367,11 +2369,11 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = { | |||
| 2367 | .to_irq = samsung_gpiolib_to_irq, | 2369 | .to_irq = samsung_gpiolib_to_irq, |
| 2368 | }, | 2370 | }, |
| 2369 | }, | 2371 | }, |
| 2370 | #endif | ||
| 2371 | }; | 2372 | }; |
| 2373 | #endif | ||
| 2372 | 2374 | ||
| 2373 | static struct samsung_gpio_chip exynos4_gpios_3[] = { | ||
| 2374 | #ifdef CONFIG_ARCH_EXYNOS4 | 2375 | #ifdef CONFIG_ARCH_EXYNOS4 |
| 2376 | static struct samsung_gpio_chip exynos4_gpios_3[] = { | ||
| 2375 | { | 2377 | { |
| 2376 | .chip = { | 2378 | .chip = { |
| 2377 | .base = EXYNOS4_GPZ(0), | 2379 | .base = EXYNOS4_GPZ(0), |
| @@ -2379,11 +2381,11 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { | |||
| 2379 | .label = "GPZ", | 2381 | .label = "GPZ", |
| 2380 | }, | 2382 | }, |
| 2381 | }, | 2383 | }, |
| 2382 | #endif | ||
| 2383 | }; | 2384 | }; |
| 2385 | #endif | ||
| 2384 | 2386 | ||
| 2385 | static struct samsung_gpio_chip exynos5_gpios_1[] = { | ||
| 2386 | #ifdef CONFIG_ARCH_EXYNOS5 | 2387 | #ifdef CONFIG_ARCH_EXYNOS5 |
| 2388 | static struct samsung_gpio_chip exynos5_gpios_1[] = { | ||
| 2387 | { | 2389 | { |
| 2388 | .chip = { | 2390 | .chip = { |
| 2389 | .base = EXYNOS5_GPA0(0), | 2391 | .base = EXYNOS5_GPA0(0), |
| @@ -2541,11 +2543,11 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { | |||
| 2541 | .to_irq = samsung_gpiolib_to_irq, | 2543 | .to_irq = samsung_gpiolib_to_irq, |
| 2542 | }, | 2544 | }, |
| 2543 | }, | 2545 | }, |
| 2544 | #endif | ||
| 2545 | }; | 2546 | }; |
| 2547 | #endif | ||
| 2546 | 2548 | ||
| 2547 | static struct samsung_gpio_chip exynos5_gpios_2[] = { | ||
| 2548 | #ifdef CONFIG_ARCH_EXYNOS5 | 2549 | #ifdef CONFIG_ARCH_EXYNOS5 |
| 2550 | static struct samsung_gpio_chip exynos5_gpios_2[] = { | ||
| 2549 | { | 2551 | { |
| 2550 | .chip = { | 2552 | .chip = { |
| 2551 | .base = EXYNOS5_GPE0(0), | 2553 | .base = EXYNOS5_GPE0(0), |
| @@ -2602,11 +2604,11 @@ static struct samsung_gpio_chip exynos5_gpios_2[] = { | |||
| 2602 | 2604 | ||
| 2603 | }, | 2605 | }, |
| 2604 | }, | 2606 | }, |
| 2605 | #endif | ||
| 2606 | }; | 2607 | }; |
| 2608 | #endif | ||
| 2607 | 2609 | ||
| 2608 | static struct samsung_gpio_chip exynos5_gpios_3[] = { | ||
| 2609 | #ifdef CONFIG_ARCH_EXYNOS5 | 2610 | #ifdef CONFIG_ARCH_EXYNOS5 |
| 2611 | static struct samsung_gpio_chip exynos5_gpios_3[] = { | ||
| 2610 | { | 2612 | { |
| 2611 | .chip = { | 2613 | .chip = { |
| 2612 | .base = EXYNOS5_GPV0(0), | 2614 | .base = EXYNOS5_GPV0(0), |
| @@ -2638,11 +2640,11 @@ static struct samsung_gpio_chip exynos5_gpios_3[] = { | |||
| 2638 | .label = "GPV4", | 2640 | .label = "GPV4", |
| 2639 | }, | 2641 | }, |
| 2640 | }, | 2642 | }, |
| 2641 | #endif | ||
| 2642 | }; | 2643 | }; |
| 2644 | #endif | ||
| 2643 | 2645 | ||
| 2644 | static struct samsung_gpio_chip exynos5_gpios_4[] = { | ||
| 2645 | #ifdef CONFIG_ARCH_EXYNOS5 | 2646 | #ifdef CONFIG_ARCH_EXYNOS5 |
| 2647 | static struct samsung_gpio_chip exynos5_gpios_4[] = { | ||
| 2646 | { | 2648 | { |
| 2647 | .chip = { | 2649 | .chip = { |
| 2648 | .base = EXYNOS5_GPZ(0), | 2650 | .base = EXYNOS5_GPZ(0), |
| @@ -2650,8 +2652,8 @@ static struct samsung_gpio_chip exynos5_gpios_4[] = { | |||
| 2650 | .label = "GPZ", | 2652 | .label = "GPZ", |
| 2651 | }, | 2653 | }, |
| 2652 | }, | 2654 | }, |
| 2653 | #endif | ||
| 2654 | }; | 2655 | }; |
| 2656 | #endif | ||
| 2655 | 2657 | ||
| 2656 | 2658 | ||
| 2657 | #if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) | 2659 | #if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) |
| @@ -2719,7 +2721,9 @@ static __init int samsung_gpiolib_init(void) | |||
| 2719 | { | 2721 | { |
| 2720 | struct samsung_gpio_chip *chip; | 2722 | struct samsung_gpio_chip *chip; |
| 2721 | int i, nr_chips; | 2723 | int i, nr_chips; |
| 2724 | #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS5250) | ||
| 2722 | void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; | 2725 | void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; |
| 2726 | #endif | ||
| 2723 | int group = 0; | 2727 | int group = 0; |
| 2724 | 2728 | ||
| 2725 | samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); | 2729 | samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); |
| @@ -2971,6 +2975,7 @@ static __init int samsung_gpiolib_init(void) | |||
| 2971 | 2975 | ||
| 2972 | return 0; | 2976 | return 0; |
| 2973 | 2977 | ||
| 2978 | #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS5250) | ||
| 2974 | err_ioremap4: | 2979 | err_ioremap4: |
| 2975 | iounmap(gpio_base3); | 2980 | iounmap(gpio_base3); |
| 2976 | err_ioremap3: | 2981 | err_ioremap3: |
| @@ -2979,6 +2984,7 @@ err_ioremap2: | |||
| 2979 | iounmap(gpio_base1); | 2984 | iounmap(gpio_base1); |
| 2980 | err_ioremap1: | 2985 | err_ioremap1: |
| 2981 | return -ENOMEM; | 2986 | return -ENOMEM; |
| 2987 | #endif | ||
| 2982 | } | 2988 | } |
| 2983 | core_initcall(samsung_gpiolib_init); | 2989 | core_initcall(samsung_gpiolib_init); |
| 2984 | 2990 | ||
diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c index 9ba15d31d242..031e5d24837d 100644 --- a/drivers/gpio/gpio-sodaville.c +++ b/drivers/gpio/gpio-sodaville.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | struct sdv_gpio_chip_data { | 41 | struct sdv_gpio_chip_data { |
| 42 | int irq_base; | 42 | int irq_base; |
| 43 | void __iomem *gpio_pub_base; | 43 | void __iomem *gpio_pub_base; |
| 44 | struct irq_domain id; | 44 | struct irq_domain *id; |
| 45 | struct irq_chip_generic *gc; | 45 | struct irq_chip_generic *gc; |
| 46 | struct bgpio_chip bgpio; | 46 | struct bgpio_chip bgpio; |
| 47 | }; | 47 | }; |
| @@ -51,10 +51,9 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) | |||
| 51 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 51 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
| 52 | struct sdv_gpio_chip_data *sd = gc->private; | 52 | struct sdv_gpio_chip_data *sd = gc->private; |
| 53 | void __iomem *type_reg; | 53 | void __iomem *type_reg; |
| 54 | u32 irq_offs = d->irq - sd->irq_base; | ||
| 55 | u32 reg; | 54 | u32 reg; |
| 56 | 55 | ||
| 57 | if (irq_offs < 8) | 56 | if (d->hwirq < 8) |
| 58 | type_reg = sd->gpio_pub_base + GPIT1R0; | 57 | type_reg = sd->gpio_pub_base + GPIT1R0; |
| 59 | else | 58 | else |
| 60 | type_reg = sd->gpio_pub_base + GPIT1R1; | 59 | type_reg = sd->gpio_pub_base + GPIT1R1; |
| @@ -63,11 +62,11 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) | |||
| 63 | 62 | ||
| 64 | switch (type) { | 63 | switch (type) { |
| 65 | case IRQ_TYPE_LEVEL_HIGH: | 64 | case IRQ_TYPE_LEVEL_HIGH: |
| 66 | reg &= ~BIT(4 * (irq_offs % 8)); | 65 | reg &= ~BIT(4 * (d->hwirq % 8)); |
| 67 | break; | 66 | break; |
| 68 | 67 | ||
| 69 | case IRQ_TYPE_LEVEL_LOW: | 68 | case IRQ_TYPE_LEVEL_LOW: |
| 70 | reg |= BIT(4 * (irq_offs % 8)); | 69 | reg |= BIT(4 * (d->hwirq % 8)); |
| 71 | break; | 70 | break; |
| 72 | 71 | ||
| 73 | default: | 72 | default: |
| @@ -91,7 +90,7 @@ static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data) | |||
| 91 | u32 irq_bit = __fls(irq_stat); | 90 | u32 irq_bit = __fls(irq_stat); |
| 92 | 91 | ||
| 93 | irq_stat &= ~BIT(irq_bit); | 92 | irq_stat &= ~BIT(irq_bit); |
| 94 | generic_handle_irq(sd->irq_base + irq_bit); | 93 | generic_handle_irq(irq_find_mapping(sd->id, irq_bit)); |
| 95 | } | 94 | } |
| 96 | 95 | ||
| 97 | return IRQ_HANDLED; | 96 | return IRQ_HANDLED; |
| @@ -127,7 +126,7 @@ static int sdv_xlate(struct irq_domain *h, struct device_node *node, | |||
| 127 | } | 126 | } |
| 128 | 127 | ||
| 129 | static struct irq_domain_ops irq_domain_sdv_ops = { | 128 | static struct irq_domain_ops irq_domain_sdv_ops = { |
| 130 | .dt_translate = sdv_xlate, | 129 | .xlate = sdv_xlate, |
| 131 | }; | 130 | }; |
| 132 | 131 | ||
| 133 | static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, | 132 | static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, |
| @@ -149,10 +148,6 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, | |||
| 149 | if (ret) | 148 | if (ret) |
| 150 | goto out_free_desc; | 149 | goto out_free_desc; |
| 151 | 150 | ||
| 152 | sd->id.irq_base = sd->irq_base; | ||
| 153 | sd->id.of_node = of_node_get(pdev->dev.of_node); | ||
| 154 | sd->id.ops = &irq_domain_sdv_ops; | ||
| 155 | |||
| 156 | /* | 151 | /* |
| 157 | * This gpio irq controller latches level irqs. Testing shows that if | 152 | * This gpio irq controller latches level irqs. Testing shows that if |
| 158 | * we unmask & ACK the IRQ before the source of the interrupt is gone | 153 | * we unmask & ACK the IRQ before the source of the interrupt is gone |
| @@ -179,7 +174,10 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, | |||
| 179 | IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, | 174 | IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, |
| 180 | IRQ_LEVEL | IRQ_NOPROBE); | 175 | IRQ_LEVEL | IRQ_NOPROBE); |
| 181 | 176 | ||
| 182 | irq_domain_add(&sd->id); | 177 | sd->id = irq_domain_add_legacy(pdev->dev.of_node, SDV_NUM_PUB_GPIOS, |
| 178 | sd->irq_base, 0, &irq_domain_sdv_ops, sd); | ||
| 179 | if (!sd->id) | ||
| 180 | goto out_free_irq; | ||
| 183 | return 0; | 181 | return 0; |
| 184 | out_free_irq: | 182 | out_free_irq: |
| 185 | free_irq(pdev->irq, sd); | 183 | free_irq(pdev->irq, sd); |
| @@ -260,7 +258,6 @@ static void sdv_gpio_remove(struct pci_dev *pdev) | |||
| 260 | { | 258 | { |
| 261 | struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev); | 259 | struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev); |
| 262 | 260 | ||
| 263 | irq_domain_del(&sd->id); | ||
| 264 | free_irq(pdev->irq, sd); | 261 | free_irq(pdev->irq, sd); |
| 265 | irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS); | 262 | irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS); |
| 266 | 263 | ||
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 32de6707e3c4..12f349b3830d 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
| 23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
| 25 | #include <linux/of.h> | 25 | #include <linux/of_device.h> |
| 26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/irqdomain.h> | 28 | #include <linux/irqdomain.h> |
| @@ -37,7 +37,8 @@ | |||
| 37 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) | 37 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) |
| 38 | #define GPIO_BIT(x) ((x) & 0x7) | 38 | #define GPIO_BIT(x) ((x) & 0x7) |
| 39 | 39 | ||
| 40 | #define GPIO_REG(x) (GPIO_BANK(x) * 0x80 + GPIO_PORT(x) * 4) | 40 | #define GPIO_REG(x) (GPIO_BANK(x) * tegra_gpio_bank_stride + \ |
| 41 | GPIO_PORT(x) * 4) | ||
| 41 | 42 | ||
| 42 | #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) | 43 | #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) |
| 43 | #define GPIO_OE(x) (GPIO_REG(x) + 0x10) | 44 | #define GPIO_OE(x) (GPIO_REG(x) + 0x10) |
| @@ -48,12 +49,12 @@ | |||
| 48 | #define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60) | 49 | #define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60) |
| 49 | #define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70) | 50 | #define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70) |
| 50 | 51 | ||
| 51 | #define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800) | 52 | #define GPIO_MSK_CNF(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x00) |
| 52 | #define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810) | 53 | #define GPIO_MSK_OE(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x10) |
| 53 | #define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820) | 54 | #define GPIO_MSK_OUT(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0X20) |
| 54 | #define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840) | 55 | #define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x40) |
| 55 | #define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850) | 56 | #define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x50) |
| 56 | #define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860) | 57 | #define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x60) |
| 57 | 58 | ||
| 58 | #define GPIO_INT_LVL_MASK 0x010101 | 59 | #define GPIO_INT_LVL_MASK 0x010101 |
| 59 | #define GPIO_INT_LVL_EDGE_RISING 0x000101 | 60 | #define GPIO_INT_LVL_EDGE_RISING 0x000101 |
| @@ -78,6 +79,8 @@ struct tegra_gpio_bank { | |||
| 78 | static struct irq_domain *irq_domain; | 79 | static struct irq_domain *irq_domain; |
| 79 | static void __iomem *regs; | 80 | static void __iomem *regs; |
| 80 | static u32 tegra_gpio_bank_count; | 81 | static u32 tegra_gpio_bank_count; |
| 82 | static u32 tegra_gpio_bank_stride; | ||
| 83 | static u32 tegra_gpio_upper_offset; | ||
| 81 | static struct tegra_gpio_bank *tegra_gpio_banks; | 84 | static struct tegra_gpio_bank *tegra_gpio_banks; |
| 82 | 85 | ||
| 83 | static inline void tegra_gpio_writel(u32 val, u32 reg) | 86 | static inline void tegra_gpio_writel(u32 val, u32 reg) |
| @@ -333,6 +336,26 @@ static struct irq_chip tegra_gpio_irq_chip = { | |||
| 333 | #endif | 336 | #endif |
| 334 | }; | 337 | }; |
| 335 | 338 | ||
| 339 | struct tegra_gpio_soc_config { | ||
| 340 | u32 bank_stride; | ||
| 341 | u32 upper_offset; | ||
| 342 | }; | ||
| 343 | |||
| 344 | static struct tegra_gpio_soc_config tegra20_gpio_config = { | ||
| 345 | .bank_stride = 0x80, | ||
| 346 | .upper_offset = 0x800, | ||
| 347 | }; | ||
| 348 | |||
| 349 | static struct tegra_gpio_soc_config tegra30_gpio_config = { | ||
| 350 | .bank_stride = 0x100, | ||
| 351 | .upper_offset = 0x80, | ||
| 352 | }; | ||
| 353 | |||
| 354 | static struct of_device_id tegra_gpio_of_match[] __devinitdata = { | ||
| 355 | { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config }, | ||
| 356 | { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config }, | ||
| 357 | { }, | ||
| 358 | }; | ||
| 336 | 359 | ||
| 337 | /* This lock class tells lockdep that GPIO irqs are in a different | 360 | /* This lock class tells lockdep that GPIO irqs are in a different |
| 338 | * category than their parents, so it won't report false recursion. | 361 | * category than their parents, so it won't report false recursion. |
| @@ -341,6 +364,8 @@ static struct lock_class_key gpio_lock_class; | |||
| 341 | 364 | ||
| 342 | static int __devinit tegra_gpio_probe(struct platform_device *pdev) | 365 | static int __devinit tegra_gpio_probe(struct platform_device *pdev) |
| 343 | { | 366 | { |
| 367 | const struct of_device_id *match; | ||
| 368 | struct tegra_gpio_soc_config *config; | ||
| 344 | int irq_base; | 369 | int irq_base; |
| 345 | struct resource *res; | 370 | struct resource *res; |
| 346 | struct tegra_gpio_bank *bank; | 371 | struct tegra_gpio_bank *bank; |
| @@ -348,6 +373,15 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
| 348 | int i; | 373 | int i; |
| 349 | int j; | 374 | int j; |
| 350 | 375 | ||
| 376 | match = of_match_device(tegra_gpio_of_match, &pdev->dev); | ||
| 377 | if (match) | ||
| 378 | config = (struct tegra_gpio_soc_config *)match->data; | ||
| 379 | else | ||
| 380 | config = &tegra20_gpio_config; | ||
| 381 | |||
| 382 | tegra_gpio_bank_stride = config->bank_stride; | ||
| 383 | tegra_gpio_upper_offset = config->upper_offset; | ||
| 384 | |||
| 351 | for (;;) { | 385 | for (;;) { |
| 352 | res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count); | 386 | res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count); |
| 353 | if (!res) | 387 | if (!res) |
| @@ -402,7 +436,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
| 402 | return -ENODEV; | 436 | return -ENODEV; |
| 403 | } | 437 | } |
| 404 | 438 | ||
| 405 | for (i = 0; i < 7; i++) { | 439 | for (i = 0; i < tegra_gpio_bank_count; i++) { |
| 406 | for (j = 0; j < 4; j++) { | 440 | for (j = 0; j < 4; j++) { |
| 407 | int gpio = tegra_gpio_compose(i, j, 0); | 441 | int gpio = tegra_gpio_compose(i, j, 0); |
| 408 | tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio)); | 442 | tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio)); |
| @@ -441,11 +475,6 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
| 441 | return 0; | 475 | return 0; |
| 442 | } | 476 | } |
| 443 | 477 | ||
| 444 | static struct of_device_id tegra_gpio_of_match[] __devinitdata = { | ||
| 445 | { .compatible = "nvidia,tegra20-gpio", }, | ||
| 446 | { }, | ||
| 447 | }; | ||
| 448 | |||
| 449 | static struct platform_driver tegra_gpio_driver = { | 478 | static struct platform_driver tegra_gpio_driver = { |
| 450 | .driver = { | 479 | .driver = { |
| 451 | .name = "tegra-gpio", | 480 | .name = "tegra-gpio", |
| @@ -485,7 +514,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) | |||
| 485 | int i; | 514 | int i; |
| 486 | int j; | 515 | int j; |
| 487 | 516 | ||
| 488 | for (i = 0; i < 7; i++) { | 517 | for (i = 0; i < tegra_gpio_bank_count; i++) { |
| 489 | for (j = 0; j < 4; j++) { | 518 | for (j = 0; j < 4; j++) { |
| 490 | int gpio = tegra_gpio_compose(i, j, 0); | 519 | int gpio = tegra_gpio_compose(i, j, 0); |
| 491 | seq_printf(s, | 520 | seq_printf(s, |
