Lines Matching +full:lock +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0+
6 * Author: David Liu <liuwei@actions-semi.com>
24 #include <linux/pinctrl/pinconf-generic.h>
29 #include "../pinctrl-utils.h"
30 #include "pinctrl-owl.h"
33 * struct owl_pinctrl - pinctrl state of the device
37 * @lock: spinlock to protect registers
49 raw_spinlock_t lock; member
74 tmp = readl_relaxed(pctrl->base + reg); in owl_read_field()
75 mask = (1 << width) - 1; in owl_read_field()
85 mask = (1 << width) - 1; in owl_write_field()
88 owl_update_bits(pctrl->base + reg, mask, (arg << bit)); in owl_write_field()
95 return pctrl->soc->ngroups; in owl_get_groups_count()
103 return pctrl->soc->groups[group].name; in owl_get_group_name()
113 *pins = pctrl->soc->groups[group].pads; in owl_get_group_pins()
114 *num_pins = pctrl->soc->groups[group].npads; in owl_get_group_pins()
121 unsigned int offset) in owl_pin_dbg_show() argument
125 seq_printf(s, "%s", dev_name(pctrl->dev)); in owl_pin_dbg_show()
141 return pctrl->soc->nfunctions; in owl_get_funcs_count()
149 return pctrl->soc->functions[function].name; in owl_get_func_name()
159 *groups = pctrl->soc->functions[function].groups; in owl_get_func_groups()
160 *num_groups = pctrl->soc->functions[function].ngroups; in owl_get_func_groups()
174 for (id = 0; id < g->nfuncs; id++) { in get_group_mfp_mask_val()
175 if (g->funcs[id] == function) in get_group_mfp_mask_val()
178 if (WARN_ON(id == g->nfuncs)) in get_group_mfp_mask_val()
179 return -EINVAL; in get_group_mfp_mask_val()
181 option_num = (1 << g->mfpctl_width); in get_group_mfp_mask_val()
183 id -= option_num; in get_group_mfp_mask_val()
185 option_mask = option_num - 1; in get_group_mfp_mask_val()
186 *mask = (option_mask << g->mfpctl_shift); in get_group_mfp_mask_val()
187 *val = (id << g->mfpctl_shift); in get_group_mfp_mask_val()
201 g = &pctrl->soc->groups[group]; in owl_set_mux()
204 return -EINVAL; in owl_set_mux()
206 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_set_mux()
208 owl_update_bits(pctrl->base + g->mfpctl_reg, mask, val); in owl_set_mux()
210 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_set_mux()
233 if (!info->pullctl) in owl_pad_pinconf_reg()
234 return -EINVAL; in owl_pad_pinconf_reg()
235 *reg = info->pullctl->reg; in owl_pad_pinconf_reg()
236 *bit = info->pullctl->shift; in owl_pad_pinconf_reg()
237 *width = info->pullctl->width; in owl_pad_pinconf_reg()
240 if (!info->st) in owl_pad_pinconf_reg()
241 return -EINVAL; in owl_pad_pinconf_reg()
242 *reg = info->st->reg; in owl_pad_pinconf_reg()
243 *bit = info->st->shift; in owl_pad_pinconf_reg()
244 *width = info->st->width; in owl_pad_pinconf_reg()
247 return -ENOTSUPP; in owl_pad_pinconf_reg()
263 info = &pctrl->soc->padinfo[pin]; in owl_pin_config_get()
271 if (!pctrl->soc->padctl_val2arg) in owl_pin_config_get()
272 return -ENOTSUPP; in owl_pin_config_get()
274 ret = pctrl->soc->padctl_val2arg(info, param, &arg); in owl_pin_config_get()
295 info = &pctrl->soc->padinfo[pin]; in owl_pin_config_set()
305 if (!pctrl->soc->padctl_arg2val) in owl_pin_config_set()
306 return -ENOTSUPP; in owl_pin_config_set()
308 ret = pctrl->soc->padctl_arg2val(info, param, &arg); in owl_pin_config_set()
312 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_pin_config_set()
316 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_pin_config_set()
330 if (g->drv_reg < 0) in owl_group_pinconf_reg()
331 return -EINVAL; in owl_group_pinconf_reg()
332 *reg = g->drv_reg; in owl_group_pinconf_reg()
333 *bit = g->drv_shift; in owl_group_pinconf_reg()
334 *width = g->drv_width; in owl_group_pinconf_reg()
337 if (g->sr_reg < 0) in owl_group_pinconf_reg()
338 return -EINVAL; in owl_group_pinconf_reg()
339 *reg = g->sr_reg; in owl_group_pinconf_reg()
340 *bit = g->sr_shift; in owl_group_pinconf_reg()
341 *width = g->sr_width; in owl_group_pinconf_reg()
344 return -ENOTSUPP; in owl_group_pinconf_reg()
370 return -EINVAL; in owl_group_pinconf_arg2val()
380 return -ENOTSUPP; in owl_group_pinconf_arg2val()
406 return -EINVAL; in owl_group_pinconf_val2arg()
416 return -ENOTSUPP; in owl_group_pinconf_val2arg()
432 g = &pctrl->soc->groups[group]; in owl_group_config_get()
462 g = &pctrl->soc->groups[group]; in owl_group_config_set()
477 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_group_config_set()
481 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_group_config_set()
507 for (i = 0; i < pctrl->soc->nports; i++) { in owl_gpio_get_port()
508 const struct owl_gpio_port *port = &pctrl->soc->ports[i]; in owl_gpio_get_port()
510 if (*pin >= start && *pin < start + port->pins) { in owl_gpio_get_port()
511 *pin -= start; in owl_gpio_get_port()
515 start += port->pins; in owl_gpio_get_port()
535 static int owl_gpio_request(struct gpio_chip *chip, unsigned int offset) in owl_gpio_request() argument
542 port = owl_gpio_get_port(pctrl, &offset); in owl_gpio_request()
544 return -ENODEV; in owl_gpio_request()
546 gpio_base = pctrl->base + port->offset; in owl_gpio_request()
552 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_request()
553 owl_gpio_update_reg(gpio_base + port->outen, offset, true); in owl_gpio_request()
554 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_request()
559 static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset) in owl_gpio_free() argument
566 port = owl_gpio_get_port(pctrl, &offset); in owl_gpio_free()
570 gpio_base = pctrl->base + port->offset; in owl_gpio_free()
572 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_free()
574 owl_gpio_update_reg(gpio_base + port->outen, offset, false); in owl_gpio_free()
577 owl_gpio_update_reg(gpio_base + port->inen, offset, false); in owl_gpio_free()
578 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_free()
581 static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset) in owl_gpio_get() argument
589 port = owl_gpio_get_port(pctrl, &offset); in owl_gpio_get()
591 return -ENODEV; in owl_gpio_get()
593 gpio_base = pctrl->base + port->offset; in owl_gpio_get()
595 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_get()
596 val = readl_relaxed(gpio_base + port->dat); in owl_gpio_get()
597 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_get()
599 return !!(val & BIT(offset)); in owl_gpio_get()
602 static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) in owl_gpio_set() argument
609 port = owl_gpio_get_port(pctrl, &offset); in owl_gpio_set()
613 gpio_base = pctrl->base + port->offset; in owl_gpio_set()
615 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_set()
616 owl_gpio_update_reg(gpio_base + port->dat, offset, value); in owl_gpio_set()
617 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_set()
620 static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) in owl_gpio_direction_input() argument
627 port = owl_gpio_get_port(pctrl, &offset); in owl_gpio_direction_input()
629 return -ENODEV; in owl_gpio_direction_input()
631 gpio_base = pctrl->base + port->offset; in owl_gpio_direction_input()
633 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_direction_input()
634 owl_gpio_update_reg(gpio_base + port->outen, offset, false); in owl_gpio_direction_input()
635 owl_gpio_update_reg(gpio_base + port->inen, offset, true); in owl_gpio_direction_input()
636 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_direction_input()
642 unsigned int offset, int value) in owl_gpio_direction_output() argument
649 port = owl_gpio_get_port(pctrl, &offset); in owl_gpio_direction_output()
651 return -ENODEV; in owl_gpio_direction_output()
653 gpio_base = pctrl->base + port->offset; in owl_gpio_direction_output()
655 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_direction_output()
656 owl_gpio_update_reg(gpio_base + port->inen, offset, false); in owl_gpio_direction_output()
657 owl_gpio_update_reg(gpio_base + port->outen, offset, true); in owl_gpio_direction_output()
658 owl_gpio_update_reg(gpio_base + port->dat, offset, value); in owl_gpio_direction_output()
659 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_direction_output()
669 unsigned int offset, value, irq_type = 0; in irq_set_type() local
679 if (owl_gpio_get(&pctrl->chip, gpio)) in irq_set_type()
709 gpio_base = pctrl->base + port->offset; in irq_set_type()
711 raw_spin_lock_irqsave(&pctrl->lock, flags); in irq_set_type()
713 offset = (gpio < 16) ? 4 : 0; in irq_set_type()
714 value = readl_relaxed(gpio_base + port->intc_type + offset); in irq_set_type()
717 writel_relaxed(value, gpio_base + port->intc_type + offset); in irq_set_type()
719 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in irq_set_type()
729 unsigned int gpio = data->hwirq; in owl_gpio_irq_mask()
736 gpio_base = pctrl->base + port->offset; in owl_gpio_irq_mask()
738 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_irq_mask()
740 owl_gpio_update_reg(gpio_base + port->intc_msk, gpio, false); in owl_gpio_irq_mask()
743 val = readl_relaxed(gpio_base + port->intc_msk); in owl_gpio_irq_mask()
745 owl_gpio_update_reg(gpio_base + port->intc_ctl, in owl_gpio_irq_mask()
746 OWL_GPIO_CTLR_ENABLE + port->shared_ctl_offset * 5, false); in owl_gpio_irq_mask()
748 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_irq_mask()
758 unsigned int gpio = data->hwirq; in owl_gpio_irq_unmask()
765 gpio_base = pctrl->base + port->offset; in owl_gpio_irq_unmask()
766 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_irq_unmask()
769 value = readl_relaxed(gpio_base + port->intc_ctl); in owl_gpio_irq_unmask()
771 << port->shared_ctl_offset * 5); in owl_gpio_irq_unmask()
772 writel_relaxed(value, gpio_base + port->intc_ctl); in owl_gpio_irq_unmask()
775 owl_gpio_update_reg(gpio_base + port->intc_msk, gpio, true); in owl_gpio_irq_unmask()
777 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_irq_unmask()
787 unsigned int gpio = data->hwirq; in owl_gpio_irq_ack()
804 gpio_base = pctrl->base + port->offset; in owl_gpio_irq_ack()
806 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_irq_ack()
808 owl_gpio_update_reg(gpio_base + port->intc_ctl, in owl_gpio_irq_ack()
809 OWL_GPIO_CTLR_PENDING + port->shared_ctl_offset * 5, true); in owl_gpio_irq_ack()
811 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_irq_ack()
824 irq_set_type(pctrl, data->hwirq, type); in owl_gpio_irq_set_type()
833 struct irq_domain *domain = pctrl->chip.irq.domain; in owl_gpio_irq_handler()
837 unsigned int pin, irq, offset = 0, i; in owl_gpio_irq_handler() local
842 for (i = 0; i < pctrl->soc->nports; i++) { in owl_gpio_irq_handler()
843 port = &pctrl->soc->ports[i]; in owl_gpio_irq_handler()
844 base = pctrl->base + port->offset; in owl_gpio_irq_handler()
847 if (parent != pctrl->irq[i]) in owl_gpio_irq_handler()
850 pending_irq = readl_relaxed(base + port->intc_pd); in owl_gpio_irq_handler()
852 for_each_set_bit(pin, &pending_irq, port->pins) { in owl_gpio_irq_handler()
853 irq = irq_find_mapping(domain, offset + pin); in owl_gpio_irq_handler()
857 owl_gpio_update_reg(base + port->intc_pd, pin, true); in owl_gpio_irq_handler()
861 offset += port->pins; in owl_gpio_irq_handler()
871 int ret, i, j, offset; in owl_gpio_init() local
873 chip = &pctrl->chip; in owl_gpio_init()
874 chip->base = -1; in owl_gpio_init()
875 chip->ngpio = pctrl->soc->ngpios; in owl_gpio_init()
876 chip->label = dev_name(pctrl->dev); in owl_gpio_init()
877 chip->parent = pctrl->dev; in owl_gpio_init()
878 chip->owner = THIS_MODULE; in owl_gpio_init()
879 chip->of_node = pctrl->dev->of_node; in owl_gpio_init()
881 pctrl->irq_chip.name = chip->of_node->name; in owl_gpio_init()
882 pctrl->irq_chip.irq_ack = owl_gpio_irq_ack; in owl_gpio_init()
883 pctrl->irq_chip.irq_mask = owl_gpio_irq_mask; in owl_gpio_init()
884 pctrl->irq_chip.irq_unmask = owl_gpio_irq_unmask; in owl_gpio_init()
885 pctrl->irq_chip.irq_set_type = owl_gpio_irq_set_type; in owl_gpio_init()
887 gpio_irq = &chip->irq; in owl_gpio_init()
888 gpio_irq->chip = &pctrl->irq_chip; in owl_gpio_init()
889 gpio_irq->handler = handle_simple_irq; in owl_gpio_init()
890 gpio_irq->default_type = IRQ_TYPE_NONE; in owl_gpio_init()
891 gpio_irq->parent_handler = owl_gpio_irq_handler; in owl_gpio_init()
892 gpio_irq->parent_handler_data = pctrl; in owl_gpio_init()
893 gpio_irq->num_parents = pctrl->num_irq; in owl_gpio_init()
894 gpio_irq->parents = pctrl->irq; in owl_gpio_init()
896 gpio_irq->map = devm_kcalloc(pctrl->dev, chip->ngpio, in owl_gpio_init()
897 sizeof(*gpio_irq->map), GFP_KERNEL); in owl_gpio_init()
898 if (!gpio_irq->map) in owl_gpio_init()
899 return -ENOMEM; in owl_gpio_init()
901 for (i = 0, offset = 0; i < pctrl->soc->nports; i++) { in owl_gpio_init()
902 const struct owl_gpio_port *port = &pctrl->soc->ports[i]; in owl_gpio_init()
904 for (j = 0; j < port->pins; j++) in owl_gpio_init()
905 gpio_irq->map[offset + j] = gpio_irq->parents[i]; in owl_gpio_init()
907 offset += port->pins; in owl_gpio_init()
910 ret = gpiochip_add_data(&pctrl->chip, pctrl); in owl_gpio_init()
912 dev_err(pctrl->dev, "failed to register gpiochip\n"); in owl_gpio_init()
925 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); in owl_pinctrl_probe()
927 return -ENOMEM; in owl_pinctrl_probe()
929 pctrl->base = devm_platform_ioremap_resource(pdev, 0); in owl_pinctrl_probe()
930 if (IS_ERR(pctrl->base)) in owl_pinctrl_probe()
931 return PTR_ERR(pctrl->base); in owl_pinctrl_probe()
934 pctrl->clk = devm_clk_get(&pdev->dev, NULL); in owl_pinctrl_probe()
935 if (IS_ERR(pctrl->clk)) { in owl_pinctrl_probe()
936 dev_err(&pdev->dev, "no clock defined\n"); in owl_pinctrl_probe()
937 return PTR_ERR(pctrl->clk); in owl_pinctrl_probe()
940 ret = clk_prepare_enable(pctrl->clk); in owl_pinctrl_probe()
942 dev_err(&pdev->dev, "clk enable failed\n"); in owl_pinctrl_probe()
946 raw_spin_lock_init(&pctrl->lock); in owl_pinctrl_probe()
948 owl_pinctrl_desc.name = dev_name(&pdev->dev); in owl_pinctrl_probe()
949 owl_pinctrl_desc.pins = soc_data->pins; in owl_pinctrl_probe()
950 owl_pinctrl_desc.npins = soc_data->npins; in owl_pinctrl_probe()
952 pctrl->chip.direction_input = owl_gpio_direction_input; in owl_pinctrl_probe()
953 pctrl->chip.direction_output = owl_gpio_direction_output; in owl_pinctrl_probe()
954 pctrl->chip.get = owl_gpio_get; in owl_pinctrl_probe()
955 pctrl->chip.set = owl_gpio_set; in owl_pinctrl_probe()
956 pctrl->chip.request = owl_gpio_request; in owl_pinctrl_probe()
957 pctrl->chip.free = owl_gpio_free; in owl_pinctrl_probe()
959 pctrl->soc = soc_data; in owl_pinctrl_probe()
960 pctrl->dev = &pdev->dev; in owl_pinctrl_probe()
962 pctrl->pctrldev = devm_pinctrl_register(&pdev->dev, in owl_pinctrl_probe()
964 if (IS_ERR(pctrl->pctrldev)) { in owl_pinctrl_probe()
965 dev_err(&pdev->dev, "could not register Actions OWL pinmux driver\n"); in owl_pinctrl_probe()
966 ret = PTR_ERR(pctrl->pctrldev); in owl_pinctrl_probe()
974 pctrl->num_irq = ret; in owl_pinctrl_probe()
976 pctrl->irq = devm_kcalloc(&pdev->dev, pctrl->num_irq, in owl_pinctrl_probe()
977 sizeof(*pctrl->irq), GFP_KERNEL); in owl_pinctrl_probe()
978 if (!pctrl->irq) { in owl_pinctrl_probe()
979 ret = -ENOMEM; in owl_pinctrl_probe()
983 for (i = 0; i < pctrl->num_irq ; i++) { in owl_pinctrl_probe()
987 pctrl->irq[i] = ret; in owl_pinctrl_probe()
999 clk_disable_unprepare(pctrl->clk); in owl_pinctrl_probe()