Loading drivers/pinctrl/qcom/pinctrl-msm.c +137 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/platform_device.h> #include <linux/pinctrl/machine.h> #include <linux/pinctrl/pinctrl.h> Loading @@ -31,7 +32,7 @@ #include <linux/reboot.h> #include <linux/pm.h> #include <linux/log2.h> #include <linux/irq.h> #include "../core.h" #include "../pinconf.h" #include "pinctrl-msm.h" Loading Loading @@ -749,6 +750,91 @@ static struct irq_chip msm_gpio_irq_chip = { .irq_set_wake = msm_gpio_irq_set_wake, }; static void msm_dirconn_irq_mask(struct irq_data *d) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_mask) parent_data->chip->irq_mask(parent_data); } static void msm_dirconn_irq_unmask(struct irq_data *d) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_unmask) parent_data->chip->irq_unmask(parent_data); } static void msm_dirconn_irq_ack(struct irq_data *d) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_ack) parent_data->chip->irq_ack(parent_data); } static void msm_dirconn_irq_eoi(struct irq_data *d) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_eoi) parent_data->chip->irq_eoi(parent_data); } static int msm_dirconn_irq_set_affinity(struct irq_data *d, const struct cpumask *maskval, bool force) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_set_affinity) return parent_data->chip->irq_set_affinity(parent_data, maskval, force); return 0; } static int msm_dirconn_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_set_vcpu_affinity) return parent_data->chip->irq_set_vcpu_affinity(parent_data, vcpu_info); return 0; } static int msm_dirconn_irq_set_type(struct irq_data *d, unsigned int type) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_set_type) return parent_data->chip->irq_set_type(parent_data, type); return 0; } static struct irq_chip msm_dirconn_irq_chip = { .name = "msmgpio-dc", .irq_mask = msm_dirconn_irq_mask, .irq_unmask = msm_dirconn_irq_unmask, .irq_eoi = msm_dirconn_irq_eoi, .irq_ack = msm_dirconn_irq_ack, .irq_set_type = msm_dirconn_irq_set_type, .irq_set_affinity = msm_dirconn_irq_set_affinity, .irq_set_vcpu_affinity = msm_dirconn_irq_set_vcpu_affinity, .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SET_TYPE_MASKED, }; static void msm_gpio_irq_handler(struct irq_desc *desc) { struct gpio_chip *gc = irq_desc_get_handler_data(desc); Loading Loading @@ -783,6 +869,55 @@ static void msm_gpio_irq_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } static void msm_gpio_dirconn_handler(struct irq_desc *desc) { struct irq_data *irqd = irq_desc_get_handler_data(desc); struct irq_chip *chip = irq_desc_get_chip(desc); chained_irq_enter(chip, desc); generic_handle_irq(irqd->irq); chained_irq_exit(chip, desc); } static void msm_gpio_setup_dir_connects(struct msm_pinctrl *pctrl) { struct device_node *parent_node; struct irq_domain *parent_domain; struct irq_fwspec fwspec; unsigned int i; parent_node = of_irq_find_parent(pctrl->dev->of_node); if (!parent_node) return; parent_domain = irq_find_host(parent_node); if (!parent_domain) return; fwspec.fwnode = parent_domain->fwnode; for (i = 0; i < pctrl->soc->n_dir_conns; i++) { const struct msm_dir_conn *dirconn = &pctrl->soc->dir_conn[i]; unsigned int parent_irq; int irq; fwspec.param[0] = 0; /* SPI */ fwspec.param[1] = dirconn->hwirq; fwspec.param[2] = IRQ_TYPE_NONE; fwspec.param_count = 3; parent_irq = irq_create_fwspec_mapping(&fwspec); irq = irq_find_mapping(pctrl->chip.irqdomain, dirconn->gpio); irq_set_parent(irq, parent_irq); irq_set_chip(irq, &msm_dirconn_irq_chip); irq_set_chip_data(irq, irq_get_irq_data(parent_irq)); __irq_set_handler(parent_irq, msm_gpio_dirconn_handler, false, NULL); irq_set_handler_data(parent_irq, irq_get_irq_data(irq)); } } static int msm_gpio_init(struct msm_pinctrl *pctrl) { struct gpio_chip *chip; Loading Loading @@ -827,6 +962,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) gpiochip_set_chained_irqchip(chip, &msm_gpio_irq_chip, pctrl->irq, msm_gpio_irq_handler); msm_gpio_setup_dir_connects(pctrl); return 0; } Loading drivers/pinctrl/qcom/pinctrl-msm.h +14 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,16 @@ struct msm_pingroup { unsigned intr_polarity_bit:5; unsigned intr_detection_bit:5; unsigned intr_detection_width:5; } /** * struct msm_dir_conn - Direct GPIO connect configuration * @gpio: GPIO pin number * @hwirq: The GIC interrupt that the pin is connected to */; struct msm_dir_conn { unsigned int gpio; irq_hw_number_t hwirq; }; /** Loading @@ -106,6 +116,8 @@ struct msm_pingroup { * @groups: An array describing all pin groups the pin SoC supports. * @ngroups: The numbmer of entries in @groups. * @ngpio: The number of pingroups the driver should expose as GPIOs. * @dir_conn: An array describing all the pins directly connected to GIC. * @ndirconns: The number of pins directly connected to GIC */ struct msm_pinctrl_soc_data { const struct pinctrl_pin_desc *pins; Loading @@ -115,6 +127,8 @@ struct msm_pinctrl_soc_data { const struct msm_pingroup *groups; unsigned ngroups; unsigned ngpios; const struct msm_dir_conn *dir_conn; unsigned int n_dir_conns; }; int msm_pinctrl_probe(struct platform_device *pdev, Loading Loading
drivers/pinctrl/qcom/pinctrl-msm.c +137 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/platform_device.h> #include <linux/pinctrl/machine.h> #include <linux/pinctrl/pinctrl.h> Loading @@ -31,7 +32,7 @@ #include <linux/reboot.h> #include <linux/pm.h> #include <linux/log2.h> #include <linux/irq.h> #include "../core.h" #include "../pinconf.h" #include "pinctrl-msm.h" Loading Loading @@ -749,6 +750,91 @@ static struct irq_chip msm_gpio_irq_chip = { .irq_set_wake = msm_gpio_irq_set_wake, }; static void msm_dirconn_irq_mask(struct irq_data *d) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_mask) parent_data->chip->irq_mask(parent_data); } static void msm_dirconn_irq_unmask(struct irq_data *d) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_unmask) parent_data->chip->irq_unmask(parent_data); } static void msm_dirconn_irq_ack(struct irq_data *d) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_ack) parent_data->chip->irq_ack(parent_data); } static void msm_dirconn_irq_eoi(struct irq_data *d) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_eoi) parent_data->chip->irq_eoi(parent_data); } static int msm_dirconn_irq_set_affinity(struct irq_data *d, const struct cpumask *maskval, bool force) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_set_affinity) return parent_data->chip->irq_set_affinity(parent_data, maskval, force); return 0; } static int msm_dirconn_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_set_vcpu_affinity) return parent_data->chip->irq_set_vcpu_affinity(parent_data, vcpu_info); return 0; } static int msm_dirconn_irq_set_type(struct irq_data *d, unsigned int type) { struct irq_desc *desc = irq_data_to_desc(d); struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq); if (parent_data->chip->irq_set_type) return parent_data->chip->irq_set_type(parent_data, type); return 0; } static struct irq_chip msm_dirconn_irq_chip = { .name = "msmgpio-dc", .irq_mask = msm_dirconn_irq_mask, .irq_unmask = msm_dirconn_irq_unmask, .irq_eoi = msm_dirconn_irq_eoi, .irq_ack = msm_dirconn_irq_ack, .irq_set_type = msm_dirconn_irq_set_type, .irq_set_affinity = msm_dirconn_irq_set_affinity, .irq_set_vcpu_affinity = msm_dirconn_irq_set_vcpu_affinity, .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SET_TYPE_MASKED, }; static void msm_gpio_irq_handler(struct irq_desc *desc) { struct gpio_chip *gc = irq_desc_get_handler_data(desc); Loading Loading @@ -783,6 +869,55 @@ static void msm_gpio_irq_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } static void msm_gpio_dirconn_handler(struct irq_desc *desc) { struct irq_data *irqd = irq_desc_get_handler_data(desc); struct irq_chip *chip = irq_desc_get_chip(desc); chained_irq_enter(chip, desc); generic_handle_irq(irqd->irq); chained_irq_exit(chip, desc); } static void msm_gpio_setup_dir_connects(struct msm_pinctrl *pctrl) { struct device_node *parent_node; struct irq_domain *parent_domain; struct irq_fwspec fwspec; unsigned int i; parent_node = of_irq_find_parent(pctrl->dev->of_node); if (!parent_node) return; parent_domain = irq_find_host(parent_node); if (!parent_domain) return; fwspec.fwnode = parent_domain->fwnode; for (i = 0; i < pctrl->soc->n_dir_conns; i++) { const struct msm_dir_conn *dirconn = &pctrl->soc->dir_conn[i]; unsigned int parent_irq; int irq; fwspec.param[0] = 0; /* SPI */ fwspec.param[1] = dirconn->hwirq; fwspec.param[2] = IRQ_TYPE_NONE; fwspec.param_count = 3; parent_irq = irq_create_fwspec_mapping(&fwspec); irq = irq_find_mapping(pctrl->chip.irqdomain, dirconn->gpio); irq_set_parent(irq, parent_irq); irq_set_chip(irq, &msm_dirconn_irq_chip); irq_set_chip_data(irq, irq_get_irq_data(parent_irq)); __irq_set_handler(parent_irq, msm_gpio_dirconn_handler, false, NULL); irq_set_handler_data(parent_irq, irq_get_irq_data(irq)); } } static int msm_gpio_init(struct msm_pinctrl *pctrl) { struct gpio_chip *chip; Loading Loading @@ -827,6 +962,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) gpiochip_set_chained_irqchip(chip, &msm_gpio_irq_chip, pctrl->irq, msm_gpio_irq_handler); msm_gpio_setup_dir_connects(pctrl); return 0; } Loading
drivers/pinctrl/qcom/pinctrl-msm.h +14 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,16 @@ struct msm_pingroup { unsigned intr_polarity_bit:5; unsigned intr_detection_bit:5; unsigned intr_detection_width:5; } /** * struct msm_dir_conn - Direct GPIO connect configuration * @gpio: GPIO pin number * @hwirq: The GIC interrupt that the pin is connected to */; struct msm_dir_conn { unsigned int gpio; irq_hw_number_t hwirq; }; /** Loading @@ -106,6 +116,8 @@ struct msm_pingroup { * @groups: An array describing all pin groups the pin SoC supports. * @ngroups: The numbmer of entries in @groups. * @ngpio: The number of pingroups the driver should expose as GPIOs. * @dir_conn: An array describing all the pins directly connected to GIC. * @ndirconns: The number of pins directly connected to GIC */ struct msm_pinctrl_soc_data { const struct pinctrl_pin_desc *pins; Loading @@ -115,6 +127,8 @@ struct msm_pinctrl_soc_data { const struct msm_pingroup *groups; unsigned ngroups; unsigned ngpios; const struct msm_dir_conn *dir_conn; unsigned int n_dir_conns; }; int msm_pinctrl_probe(struct platform_device *pdev, Loading