Lines Matching +full:big +full:- +full:endian +full:- +full:desc
2 * Copyright (C) 2015-2017 Broadcom
71 #define GPIO_BIT(gpio) ((gpio) & (MAX_GPIO_PER_BANK - 1))
77 return bank->parent_priv; in brcmstb_gpio_gc_to_priv()
83 void __iomem *reg_base = bank->parent_priv->reg_base; in __brcmstb_gpio_get_active_irqs()
85 return bank->gc.read_reg(reg_base + GIO_STAT(bank->id)) & in __brcmstb_gpio_get_active_irqs()
86 bank->gc.read_reg(reg_base + GIO_MASK(bank->id)); in __brcmstb_gpio_get_active_irqs()
95 spin_lock_irqsave(&bank->gc.bgpio_lock, flags); in brcmstb_gpio_get_active_irqs()
97 spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags); in brcmstb_gpio_get_active_irqs()
105 return hwirq - (bank->gc.base - bank->parent_priv->gpio_base); in brcmstb_gpio_hwirq_to_offset()
111 struct gpio_chip *gc = &bank->gc; in brcmstb_gpio_set_imask()
112 struct brcmstb_gpio_priv *priv = bank->parent_priv; in brcmstb_gpio_set_imask()
117 spin_lock_irqsave(&gc->bgpio_lock, flags); in brcmstb_gpio_set_imask()
118 imask = gc->read_reg(priv->reg_base + GIO_MASK(bank->id)); in brcmstb_gpio_set_imask()
123 gc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask); in brcmstb_gpio_set_imask()
124 spin_unlock_irqrestore(&gc->bgpio_lock, flags); in brcmstb_gpio_set_imask()
131 int hwirq = offset + (gc->base - priv->gpio_base); in brcmstb_gpio_to_irq()
133 if (hwirq >= priv->num_gpios) in brcmstb_gpio_to_irq()
134 return -ENXIO; in brcmstb_gpio_to_irq()
135 return irq_create_mapping(priv->irq_domain, hwirq); in brcmstb_gpio_to_irq()
138 /* -------------------- IRQ chip functions -------------------- */
145 brcmstb_gpio_set_imask(bank, d->hwirq, false); in brcmstb_gpio_irq_mask()
153 brcmstb_gpio_set_imask(bank, d->hwirq, true); in brcmstb_gpio_irq_unmask()
160 struct brcmstb_gpio_priv *priv = bank->parent_priv; in brcmstb_gpio_irq_ack()
161 u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank)); in brcmstb_gpio_irq_ack()
163 gc->write_reg(priv->reg_base + GIO_STAT(bank->id), mask); in brcmstb_gpio_irq_ack()
170 struct brcmstb_gpio_priv *priv = bank->parent_priv; in brcmstb_gpio_irq_set_type()
171 u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank)); in brcmstb_gpio_irq_set_type()
204 return -EINVAL; in brcmstb_gpio_irq_set_type()
207 spin_lock_irqsave(&bank->gc.bgpio_lock, flags); in brcmstb_gpio_irq_set_type()
209 iedge_config = bank->gc.read_reg(priv->reg_base + in brcmstb_gpio_irq_set_type()
210 GIO_EC(bank->id)) & ~mask; in brcmstb_gpio_irq_set_type()
211 iedge_insensitive = bank->gc.read_reg(priv->reg_base + in brcmstb_gpio_irq_set_type()
212 GIO_EI(bank->id)) & ~mask; in brcmstb_gpio_irq_set_type()
213 ilevel = bank->gc.read_reg(priv->reg_base + in brcmstb_gpio_irq_set_type()
214 GIO_LEVEL(bank->id)) & ~mask; in brcmstb_gpio_irq_set_type()
216 bank->gc.write_reg(priv->reg_base + GIO_EC(bank->id), in brcmstb_gpio_irq_set_type()
218 bank->gc.write_reg(priv->reg_base + GIO_EI(bank->id), in brcmstb_gpio_irq_set_type()
220 bank->gc.write_reg(priv->reg_base + GIO_LEVEL(bank->id), in brcmstb_gpio_irq_set_type()
223 spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags); in brcmstb_gpio_irq_set_type()
233 ret = enable_irq_wake(priv->parent_wake_irq); in brcmstb_gpio_priv_set_wake()
235 ret = disable_irq_wake(priv->parent_wake_irq); in brcmstb_gpio_priv_set_wake()
237 dev_err(&priv->pdev->dev, "failed to %s wake-up interrupt\n", in brcmstb_gpio_priv_set_wake()
246 struct brcmstb_gpio_priv *priv = bank->parent_priv; in brcmstb_gpio_irq_set_wake()
247 u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank)); in brcmstb_gpio_irq_set_wake()
254 bank->wake_active |= mask; in brcmstb_gpio_irq_set_wake()
256 bank->wake_active &= ~mask; in brcmstb_gpio_irq_set_wake()
265 if (!priv || irq != priv->parent_wake_irq) in brcmstb_gpio_wake_irq_handler()
274 struct brcmstb_gpio_priv *priv = bank->parent_priv; in brcmstb_gpio_irq_bank_handler()
275 struct irq_domain *domain = priv->irq_domain; in brcmstb_gpio_irq_bank_handler()
276 int hwbase = bank->gc.base - priv->gpio_base; in brcmstb_gpio_irq_bank_handler()
283 if (offset >= bank->width) in brcmstb_gpio_irq_bank_handler()
284 dev_warn(&priv->pdev->dev, in brcmstb_gpio_irq_bank_handler()
286 bank->id, offset); in brcmstb_gpio_irq_bank_handler()
294 static void brcmstb_gpio_irq_handler(struct irq_desc *desc) in brcmstb_gpio_irq_handler() argument
296 struct brcmstb_gpio_priv *priv = irq_desc_get_handler_data(desc); in brcmstb_gpio_irq_handler()
297 struct irq_chip *chip = irq_desc_get_chip(desc); in brcmstb_gpio_irq_handler()
303 chained_irq_enter(chip, desc); in brcmstb_gpio_irq_handler()
304 list_for_each_entry(bank, &priv->bank_list, node) in brcmstb_gpio_irq_handler()
306 chained_irq_exit(chip, desc); in brcmstb_gpio_irq_handler()
316 list_for_each_entry_reverse(bank, &priv->bank_list, node) { in brcmstb_gpio_hwirq_to_bank()
317 i += bank->gc.ngpio; in brcmstb_gpio_hwirq_to_bank()
335 struct brcmstb_gpio_priv *priv = d->host_data; in brcmstb_gpio_irq_map()
338 struct platform_device *pdev = priv->pdev; in brcmstb_gpio_irq_map()
342 return -EINVAL; in brcmstb_gpio_irq_map()
344 dev_dbg(&pdev->dev, "Mapping irq %d for gpio line %d (bank %d)\n", in brcmstb_gpio_irq_map()
345 irq, (int)hwirq, bank->id); in brcmstb_gpio_irq_map()
346 ret = irq_set_chip_data(irq, &bank->gc); in brcmstb_gpio_irq_map()
351 irq_set_chip_and_handler(irq, &priv->irq_chip, handle_level_irq); in brcmstb_gpio_irq_map()
374 of_property_count_u32_elems(np, "brcm,gpio-bank-widths"); in brcmstb_gpio_sanity_check_banks()
377 dev_err(dev, "Mismatch in banks: res had %d, bank-widths had %d\n", in brcmstb_gpio_sanity_check_banks()
379 return -EINVAL; in brcmstb_gpio_sanity_check_banks()
392 dev_err(&pdev->dev, "called %s without drvdata!\n", __func__); in brcmstb_gpio_remove()
393 return -EFAULT; in brcmstb_gpio_remove()
396 if (priv->parent_irq > 0) in brcmstb_gpio_remove()
397 irq_set_chained_handler_and_data(priv->parent_irq, NULL, NULL); in brcmstb_gpio_remove()
400 if (priv->irq_domain) { in brcmstb_gpio_remove()
401 for (offset = 0; offset < priv->num_gpios; offset++) { in brcmstb_gpio_remove()
402 virq = irq_find_mapping(priv->irq_domain, offset); in brcmstb_gpio_remove()
405 irq_domain_remove(priv->irq_domain); in brcmstb_gpio_remove()
412 list_for_each_entry(bank, &priv->bank_list, node) in brcmstb_gpio_remove()
413 gpiochip_remove(&bank->gc); in brcmstb_gpio_remove()
425 if (gc->of_gpio_n_cells != 2) { in brcmstb_gpio_of_xlate()
427 return -EINVAL; in brcmstb_gpio_of_xlate()
430 if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) in brcmstb_gpio_of_xlate()
431 return -EINVAL; in brcmstb_gpio_of_xlate()
433 offset = gpiospec->args[0] - (gc->base - priv->gpio_base); in brcmstb_gpio_of_xlate()
434 if (offset >= gc->ngpio || offset < 0) in brcmstb_gpio_of_xlate()
435 return -EINVAL; in brcmstb_gpio_of_xlate()
437 if (unlikely(offset >= bank->width)) { in brcmstb_gpio_of_xlate()
438 dev_warn_ratelimited(&priv->pdev->dev, in brcmstb_gpio_of_xlate()
440 gpiospec->args[0]); in brcmstb_gpio_of_xlate()
444 *flags = gpiospec->args[1]; in brcmstb_gpio_of_xlate()
449 /* priv->parent_irq and priv->num_gpios must be set before calling */
453 struct device *dev = &pdev->dev; in brcmstb_gpio_irq_setup()
454 struct device_node *np = dev->of_node; in brcmstb_gpio_irq_setup()
457 priv->irq_domain = in brcmstb_gpio_irq_setup()
458 irq_domain_add_linear(np, priv->num_gpios, in brcmstb_gpio_irq_setup()
461 if (!priv->irq_domain) { in brcmstb_gpio_irq_setup()
463 return -ENXIO; in brcmstb_gpio_irq_setup()
466 if (of_property_read_bool(np, "wakeup-source")) { in brcmstb_gpio_irq_setup()
467 priv->parent_wake_irq = platform_get_irq(pdev, 1); in brcmstb_gpio_irq_setup()
468 if (priv->parent_wake_irq < 0) { in brcmstb_gpio_irq_setup()
469 priv->parent_wake_irq = 0; in brcmstb_gpio_irq_setup()
471 "Couldn't get wake IRQ - GPIOs will not be able to wake from sleep"); in brcmstb_gpio_irq_setup()
474 * Set wakeup capability so we can process boot-time in brcmstb_gpio_irq_setup()
479 err = devm_request_irq(dev, priv->parent_wake_irq, in brcmstb_gpio_irq_setup()
482 "brcmstb-gpio-wake", priv); in brcmstb_gpio_irq_setup()
491 priv->irq_chip.name = dev_name(dev); in brcmstb_gpio_irq_setup()
492 priv->irq_chip.irq_disable = brcmstb_gpio_irq_mask; in brcmstb_gpio_irq_setup()
493 priv->irq_chip.irq_mask = brcmstb_gpio_irq_mask; in brcmstb_gpio_irq_setup()
494 priv->irq_chip.irq_unmask = brcmstb_gpio_irq_unmask; in brcmstb_gpio_irq_setup()
495 priv->irq_chip.irq_ack = brcmstb_gpio_irq_ack; in brcmstb_gpio_irq_setup()
496 priv->irq_chip.irq_set_type = brcmstb_gpio_irq_set_type; in brcmstb_gpio_irq_setup()
498 if (priv->parent_wake_irq) in brcmstb_gpio_irq_setup()
499 priv->irq_chip.irq_set_wake = brcmstb_gpio_irq_set_wake; in brcmstb_gpio_irq_setup()
501 irq_set_chained_handler_and_data(priv->parent_irq, in brcmstb_gpio_irq_setup()
503 irq_set_status_flags(priv->parent_irq, IRQ_DISABLE_UNLAZY); in brcmstb_gpio_irq_setup()
508 irq_domain_remove(priv->irq_domain); in brcmstb_gpio_irq_setup()
516 struct gpio_chip *gc = &bank->gc; in brcmstb_gpio_bank_save()
520 bank->saved_regs[i] = gc->read_reg(priv->reg_base + in brcmstb_gpio_bank_save()
521 GIO_BANK_OFF(bank->id, i)); in brcmstb_gpio_bank_save()
531 /* disable non-wake interrupt */ in brcmstb_gpio_quiesce()
532 if (priv->parent_irq >= 0) in brcmstb_gpio_quiesce()
533 disable_irq(priv->parent_irq); in brcmstb_gpio_quiesce()
535 list_for_each_entry(bank, &priv->bank_list, node) { in brcmstb_gpio_quiesce()
536 gc = &bank->gc; in brcmstb_gpio_quiesce()
541 /* Unmask GPIOs which have been flagged as wake-up sources */ in brcmstb_gpio_quiesce()
542 if (priv->parent_wake_irq) in brcmstb_gpio_quiesce()
543 imask = bank->wake_active; in brcmstb_gpio_quiesce()
546 gc->write_reg(priv->reg_base + GIO_MASK(bank->id), in brcmstb_gpio_quiesce()
554 brcmstb_gpio_quiesce(&pdev->dev, false); in brcmstb_gpio_shutdown()
561 struct gpio_chip *gc = &bank->gc; in brcmstb_gpio_bank_restore()
565 gc->write_reg(priv->reg_base + GIO_BANK_OFF(bank->id, i), in brcmstb_gpio_bank_restore()
566 bank->saved_regs[i]); in brcmstb_gpio_bank_restore()
581 list_for_each_entry(bank, &priv->bank_list, node) { in brcmstb_gpio_resume()
586 if (priv->parent_wake_irq && need_wakeup_event) in brcmstb_gpio_resume()
589 /* enable non-wake interrupt */ in brcmstb_gpio_resume()
590 if (priv->parent_irq >= 0) in brcmstb_gpio_resume()
591 enable_irq(priv->parent_irq); in brcmstb_gpio_resume()
609 struct device_node *np = dev->of_node; in brcmstb_gpio_set_names()
614 base = bank->id * MAX_GPIO_PER_BANK; in brcmstb_gpio_set_names()
616 nstrings = of_property_count_strings(np, "gpio-line-names"); in brcmstb_gpio_set_names()
630 for (i = 0; i < bank->width; i++) { in brcmstb_gpio_set_names()
634 ret = of_property_read_string_index(np, "gpio-line-names", in brcmstb_gpio_set_names()
637 if (ret != -ENODATA) in brcmstb_gpio_set_names()
646 bank->gc.names = names; in brcmstb_gpio_set_names()
651 struct device *dev = &pdev->dev; in brcmstb_gpio_probe()
652 struct device_node *np = dev->of_node; in brcmstb_gpio_probe()
667 return -ENOMEM; in brcmstb_gpio_probe()
669 INIT_LIST_HEAD(&priv->bank_list); in brcmstb_gpio_probe()
676 priv->gpio_base = gpio_base; in brcmstb_gpio_probe()
677 priv->reg_base = reg_base; in brcmstb_gpio_probe()
678 priv->pdev = pdev; in brcmstb_gpio_probe()
680 if (of_property_read_bool(np, "interrupt-controller")) { in brcmstb_gpio_probe()
681 priv->parent_irq = platform_get_irq(pdev, 0); in brcmstb_gpio_probe()
682 if (priv->parent_irq <= 0) in brcmstb_gpio_probe()
683 return -ENOENT; in brcmstb_gpio_probe()
685 priv->parent_irq = -ENOENT; in brcmstb_gpio_probe()
689 return -EINVAL; in brcmstb_gpio_probe()
693 * bus endianness (i.e., big-endian CPU + big endian bus ==> native in brcmstb_gpio_probe()
694 * endian I/O). in brcmstb_gpio_probe()
696 * Other architectures (e.g., ARM) either do not support big endian, or in brcmstb_gpio_probe()
697 * else leave I/O in little endian mode. in brcmstb_gpio_probe()
703 of_property_for_each_u32(np, "brcm,gpio-bank-widths", prop, p, in brcmstb_gpio_probe()
722 err = -ENOMEM; in brcmstb_gpio_probe()
726 bank->parent_priv = priv; in brcmstb_gpio_probe()
727 bank->id = num_banks; in brcmstb_gpio_probe()
730 err = -EINVAL; in brcmstb_gpio_probe()
733 bank->width = bank_width; in brcmstb_gpio_probe()
740 gc = &bank->gc; in brcmstb_gpio_probe()
742 reg_base + GIO_DATA(bank->id), in brcmstb_gpio_probe()
744 reg_base + GIO_IODIR(bank->id), flags); in brcmstb_gpio_probe()
750 gc->of_node = np; in brcmstb_gpio_probe()
751 gc->owner = THIS_MODULE; in brcmstb_gpio_probe()
752 gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", dev->of_node); in brcmstb_gpio_probe()
753 if (!gc->label) { in brcmstb_gpio_probe()
754 err = -ENOMEM; in brcmstb_gpio_probe()
757 gc->base = gpio_base; in brcmstb_gpio_probe()
758 gc->of_gpio_n_cells = 2; in brcmstb_gpio_probe()
759 gc->of_xlate = brcmstb_gpio_of_xlate; in brcmstb_gpio_probe()
761 gc->ngpio = MAX_GPIO_PER_BANK; in brcmstb_gpio_probe()
762 if (priv->parent_irq > 0) in brcmstb_gpio_probe()
763 gc->to_irq = brcmstb_gpio_to_irq; in brcmstb_gpio_probe()
770 gc->write_reg(reg_base + GIO_MASK(bank->id), 0); in brcmstb_gpio_probe()
776 bank->id); in brcmstb_gpio_probe()
779 gpio_base += gc->ngpio; in brcmstb_gpio_probe()
781 dev_dbg(dev, "bank=%d, base=%d, ngpio=%d, width=%d\n", bank->id, in brcmstb_gpio_probe()
782 gc->base, gc->ngpio, bank->width); in brcmstb_gpio_probe()
785 list_add(&bank->node, &priv->bank_list); in brcmstb_gpio_probe()
790 priv->num_gpios = gpio_base - priv->gpio_base; in brcmstb_gpio_probe()
791 if (priv->parent_irq > 0) { in brcmstb_gpio_probe()
797 if (priv->parent_wake_irq && need_wakeup_event) in brcmstb_gpio_probe()
808 { .compatible = "brcm,brcmstb-gpio" },
816 .name = "brcmstb-gpio",