Commit 1b5caa3e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pinctrl-v4.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control fixes from Linus Walleij:
 "Here is a set of pin control fixes for the v4.6 series.

  A bit bigger than what I hoped for, but all fixes are confined to
  drivers, a few of them also targeted to stable.

  Summary:

   - On Super-H PFC (Renesas) controllers: only use dummies on legacy
     systems.  This fixes a serious ethernet regression on a Renesas
     board.
   - Pistachio: Fix errors in the pin table.
   - Allwinner SunXi: fix the external interrupts to work.
   - Intel: fix so the high level interrupts start working, and fix a
     spurious interrupt issue.
   - Qualcomm ipq4019: fix the number of GPIOs provided (bump to 100),
     correct register offsets and handle GPIO mode properly.
   - Revert the revert on the revert so that Xway has a .to_irq()
     callback again.
   - Minor fixes to errorpaths and debug info.
   - A MAINTAINERS update"

* tag 'pinctrl-v4.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  Revert "Revert "pinctrl: lantiq: Implement gpio_chip.to_irq""
  pinctrl: qcom: ipq4019: fix register offsets
  pinctrl: qcom: ipq4019: fix the function enum for gpio mode
  pinctrl: qcom: ipq4019: set ngpios to correct value
  pinctrl: nomadik: fix pull debug print inversion
  MAINTAINERS: pinctrl: samsung: Add two new maintainers
  pinctrl: intel: implement gpio_irq_enable
  pinctrl: intel: make the high level interrupt working
  pinctrl: freescale: imx: fix bogus check of of_iomap() return value
  pinctrl: sunxi: Fix A33 external interrupts not working
  pinctrl: pistachio: fix mfio84-89 function description and pinmux.
  pinctrl: sh-pfc: only use dummy states for non-DT platforms
parents 62d2def9 e1641c9d
...@@ -134,12 +134,12 @@ mfio80 ddr_debug, mips_trace_data, mips_debug ...@@ -134,12 +134,12 @@ mfio80 ddr_debug, mips_trace_data, mips_debug
mfio81 dreq0, mips_trace_data, eth_debug mfio81 dreq0, mips_trace_data, eth_debug
mfio82 dreq1, mips_trace_data, eth_debug mfio82 dreq1, mips_trace_data, eth_debug
mfio83 mips_pll_lock, mips_trace_data, usb_debug mfio83 mips_pll_lock, mips_trace_data, usb_debug
mfio84 sys_pll_lock, mips_trace_data, usb_debug mfio84 audio_pll_lock, mips_trace_data, usb_debug
mfio85 wifi_pll_lock, mips_trace_data, sdhost_debug mfio85 rpu_v_pll_lock, mips_trace_data, sdhost_debug
mfio86 bt_pll_lock, mips_trace_data, sdhost_debug mfio86 rpu_l_pll_lock, mips_trace_data, sdhost_debug
mfio87 rpu_v_pll_lock, dreq2, socif_debug mfio87 sys_pll_lock, dreq2, socif_debug
mfio88 rpu_l_pll_lock, dreq3, socif_debug mfio88 wifi_pll_lock, dreq3, socif_debug
mfio89 audio_pll_lock, dreq4, dreq5 mfio89 bt_pll_lock, dreq4, dreq5
tck tck
trstn trstn
tdi tdi
......
...@@ -8712,6 +8712,8 @@ F: drivers/pinctrl/sh-pfc/ ...@@ -8712,6 +8712,8 @@ F: drivers/pinctrl/sh-pfc/
PIN CONTROLLER - SAMSUNG PIN CONTROLLER - SAMSUNG
M: Tomasz Figa <tomasz.figa@gmail.com> M: Tomasz Figa <tomasz.figa@gmail.com>
M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
S: Maintained S: Maintained
......
...@@ -762,19 +762,18 @@ int imx_pinctrl_probe(struct platform_device *pdev, ...@@ -762,19 +762,18 @@ int imx_pinctrl_probe(struct platform_device *pdev,
if (of_property_read_bool(dev_np, "fsl,input-sel")) { if (of_property_read_bool(dev_np, "fsl,input-sel")) {
np = of_parse_phandle(dev_np, "fsl,input-sel", 0); np = of_parse_phandle(dev_np, "fsl,input-sel", 0);
if (np) { if (!np) {
ipctl->input_sel_base = of_iomap(np, 0);
if (IS_ERR(ipctl->input_sel_base)) {
of_node_put(np);
dev_err(&pdev->dev,
"iomuxc input select base address not found\n");
return PTR_ERR(ipctl->input_sel_base);
}
} else {
dev_err(&pdev->dev, "iomuxc fsl,input-sel property not found\n"); dev_err(&pdev->dev, "iomuxc fsl,input-sel property not found\n");
return -EINVAL; return -EINVAL;
} }
ipctl->input_sel_base = of_iomap(np, 0);
of_node_put(np); of_node_put(np);
if (!ipctl->input_sel_base) {
dev_err(&pdev->dev,
"iomuxc input select base address not found\n");
return -ENOMEM;
}
} }
imx_pinctrl_desc.name = dev_name(&pdev->dev); imx_pinctrl_desc.name = dev_name(&pdev->dev);
......
...@@ -665,6 +665,35 @@ static void intel_gpio_irq_ack(struct irq_data *d) ...@@ -665,6 +665,35 @@ static void intel_gpio_irq_ack(struct irq_data *d)
spin_unlock(&pctrl->lock); spin_unlock(&pctrl->lock);
} }
static void intel_gpio_irq_enable(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
unsigned long flags;
spin_lock_irqsave(&pctrl->lock, flags);
community = intel_get_community(pctrl, pin);
if (community) {
unsigned padno = pin_to_padno(community, pin);
unsigned gpp_size = community->gpp_size;
unsigned gpp_offset = padno % gpp_size;
unsigned gpp = padno / gpp_size;
u32 value;
/* Clear interrupt status first to avoid unexpected interrupt */
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
value = readl(community->regs + community->ie_offset + gpp * 4);
value |= BIT(gpp_offset);
writel(value, community->regs + community->ie_offset + gpp * 4);
}
spin_unlock_irqrestore(&pctrl->lock, flags);
}
static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
{ {
struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
...@@ -741,8 +770,9 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type) ...@@ -741,8 +770,9 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
value |= PADCFG0_RXINV; value |= PADCFG0_RXINV;
} else if (type & IRQ_TYPE_EDGE_RISING) { } else if (type & IRQ_TYPE_EDGE_RISING) {
value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT; value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT;
} else if (type & IRQ_TYPE_LEVEL_LOW) { } else if (type & IRQ_TYPE_LEVEL_MASK) {
value |= PADCFG0_RXINV; if (type & IRQ_TYPE_LEVEL_LOW)
value |= PADCFG0_RXINV;
} else { } else {
value |= PADCFG0_RXEVCFG_DISABLED << PADCFG0_RXEVCFG_SHIFT; value |= PADCFG0_RXEVCFG_DISABLED << PADCFG0_RXEVCFG_SHIFT;
} }
...@@ -852,6 +882,7 @@ static irqreturn_t intel_gpio_irq(int irq, void *data) ...@@ -852,6 +882,7 @@ static irqreturn_t intel_gpio_irq(int irq, void *data)
static struct irq_chip intel_gpio_irqchip = { static struct irq_chip intel_gpio_irqchip = {
.name = "intel-gpio", .name = "intel-gpio",
.irq_enable = intel_gpio_irq_enable,
.irq_ack = intel_gpio_irq_ack, .irq_ack = intel_gpio_irq_ack,
.irq_mask = intel_gpio_irq_mask, .irq_mask = intel_gpio_irq_mask,
.irq_unmask = intel_gpio_irq_unmask, .irq_unmask = intel_gpio_irq_unmask,
......
...@@ -990,7 +990,7 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s, ...@@ -990,7 +990,7 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
int val; int val;
if (pull) if (pull)
pullidx = data_out ? 1 : 2; pullidx = data_out ? 2 : 1;
seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s", seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s",
gpio, gpio,
......
...@@ -469,27 +469,27 @@ static const char * const pistachio_mips_pll_lock_groups[] = { ...@@ -469,27 +469,27 @@ static const char * const pistachio_mips_pll_lock_groups[] = {
"mfio83", "mfio83",
}; };
static const char * const pistachio_sys_pll_lock_groups[] = { static const char * const pistachio_audio_pll_lock_groups[] = {
"mfio84", "mfio84",
}; };
static const char * const pistachio_wifi_pll_lock_groups[] = { static const char * const pistachio_rpu_v_pll_lock_groups[] = {
"mfio85", "mfio85",
}; };
static const char * const pistachio_bt_pll_lock_groups[] = { static const char * const pistachio_rpu_l_pll_lock_groups[] = {
"mfio86", "mfio86",
}; };
static const char * const pistachio_rpu_v_pll_lock_groups[] = { static const char * const pistachio_sys_pll_lock_groups[] = {
"mfio87", "mfio87",
}; };
static const char * const pistachio_rpu_l_pll_lock_groups[] = { static const char * const pistachio_wifi_pll_lock_groups[] = {
"mfio88", "mfio88",
}; };
static const char * const pistachio_audio_pll_lock_groups[] = { static const char * const pistachio_bt_pll_lock_groups[] = {
"mfio89", "mfio89",
}; };
...@@ -559,12 +559,12 @@ enum pistachio_mux_option { ...@@ -559,12 +559,12 @@ enum pistachio_mux_option {
PISTACHIO_FUNCTION_DREQ4, PISTACHIO_FUNCTION_DREQ4,
PISTACHIO_FUNCTION_DREQ5, PISTACHIO_FUNCTION_DREQ5,
PISTACHIO_FUNCTION_MIPS_PLL_LOCK, PISTACHIO_FUNCTION_MIPS_PLL_LOCK,
PISTACHIO_FUNCTION_AUDIO_PLL_LOCK,
PISTACHIO_FUNCTION_RPU_V_PLL_LOCK,
PISTACHIO_FUNCTION_RPU_L_PLL_LOCK,
PISTACHIO_FUNCTION_SYS_PLL_LOCK, PISTACHIO_FUNCTION_SYS_PLL_LOCK,
PISTACHIO_FUNCTION_WIFI_PLL_LOCK, PISTACHIO_FUNCTION_WIFI_PLL_LOCK,
PISTACHIO_FUNCTION_BT_PLL_LOCK, PISTACHIO_FUNCTION_BT_PLL_LOCK,
PISTACHIO_FUNCTION_RPU_V_PLL_LOCK,
PISTACHIO_FUNCTION_RPU_L_PLL_LOCK,
PISTACHIO_FUNCTION_AUDIO_PLL_LOCK,
PISTACHIO_FUNCTION_DEBUG_RAW_CCA_IND, PISTACHIO_FUNCTION_DEBUG_RAW_CCA_IND,
PISTACHIO_FUNCTION_DEBUG_ED_SEC20_CCA_IND, PISTACHIO_FUNCTION_DEBUG_ED_SEC20_CCA_IND,
PISTACHIO_FUNCTION_DEBUG_ED_SEC40_CCA_IND, PISTACHIO_FUNCTION_DEBUG_ED_SEC40_CCA_IND,
...@@ -620,12 +620,12 @@ static const struct pistachio_function pistachio_functions[] = { ...@@ -620,12 +620,12 @@ static const struct pistachio_function pistachio_functions[] = {
FUNCTION(dreq4), FUNCTION(dreq4),
FUNCTION(dreq5), FUNCTION(dreq5),
FUNCTION(mips_pll_lock), FUNCTION(mips_pll_lock),
FUNCTION(audio_pll_lock),
FUNCTION(rpu_v_pll_lock),
FUNCTION(rpu_l_pll_lock),
FUNCTION(sys_pll_lock), FUNCTION(sys_pll_lock),
FUNCTION(wifi_pll_lock), FUNCTION(wifi_pll_lock),
FUNCTION(bt_pll_lock), FUNCTION(bt_pll_lock),
FUNCTION(rpu_v_pll_lock),
FUNCTION(rpu_l_pll_lock),
FUNCTION(audio_pll_lock),
FUNCTION(debug_raw_cca_ind), FUNCTION(debug_raw_cca_ind),
FUNCTION(debug_ed_sec20_cca_ind), FUNCTION(debug_ed_sec20_cca_ind),
FUNCTION(debug_ed_sec40_cca_ind), FUNCTION(debug_ed_sec40_cca_ind),
......
...@@ -1573,6 +1573,22 @@ static int xway_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, int val) ...@@ -1573,6 +1573,22 @@ static int xway_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, int val)
return 0; return 0;
} }
/*
* gpiolib gpiod_to_irq callback function.
* Returns the mapped IRQ (external interrupt) number for a given GPIO pin.
*/
static int xway_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct ltq_pinmux_info *info = dev_get_drvdata(chip->parent);
int i;
for (i = 0; i < info->num_exin; i++)
if (info->exin[i] == offset)
return ltq_eiu_get_irq(i);
return -1;
}
static struct gpio_chip xway_chip = { static struct gpio_chip xway_chip = {
.label = "gpio-xway", .label = "gpio-xway",
.direction_input = xway_gpio_dir_in, .direction_input = xway_gpio_dir_in,
...@@ -1581,6 +1597,7 @@ static struct gpio_chip xway_chip = { ...@@ -1581,6 +1597,7 @@ static struct gpio_chip xway_chip = {
.set = xway_gpio_set, .set = xway_gpio_set,
.request = gpiochip_generic_request, .request = gpiochip_generic_request,
.free = gpiochip_generic_free, .free = gpiochip_generic_free,
.to_irq = xway_gpio_to_irq,
.base = -1, .base = -1,
}; };
......
...@@ -237,7 +237,7 @@ DECLARE_QCA_GPIO_PINS(99); ...@@ -237,7 +237,7 @@ DECLARE_QCA_GPIO_PINS(99);
.pins = gpio##id##_pins, \ .pins = gpio##id##_pins, \
.npins = (unsigned)ARRAY_SIZE(gpio##id##_pins), \ .npins = (unsigned)ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \ .funcs = (int[]){ \
qca_mux_NA, /* gpio mode */ \ qca_mux_gpio, /* gpio mode */ \
qca_mux_##f1, \ qca_mux_##f1, \
qca_mux_##f2, \ qca_mux_##f2, \
qca_mux_##f3, \ qca_mux_##f3, \
...@@ -254,11 +254,11 @@ DECLARE_QCA_GPIO_PINS(99); ...@@ -254,11 +254,11 @@ DECLARE_QCA_GPIO_PINS(99);
qca_mux_##f14 \ qca_mux_##f14 \
}, \ }, \
.nfuncs = 15, \ .nfuncs = 15, \
.ctl_reg = 0x1000 + 0x10 * id, \ .ctl_reg = 0x0 + 0x1000 * id, \
.io_reg = 0x1004 + 0x10 * id, \ .io_reg = 0x4 + 0x1000 * id, \
.intr_cfg_reg = 0x1008 + 0x10 * id, \ .intr_cfg_reg = 0x8 + 0x1000 * id, \
.intr_status_reg = 0x100c + 0x10 * id, \ .intr_status_reg = 0xc + 0x1000 * id, \
.intr_target_reg = 0x400 + 0x4 * id, \ .intr_target_reg = 0x8 + 0x1000 * id, \
.mux_bit = 2, \ .mux_bit = 2, \
.pull_bit = 0, \ .pull_bit = 0, \
.drv_bit = 6, \ .drv_bit = 6, \
...@@ -414,7 +414,7 @@ static const struct msm_pinctrl_soc_data ipq4019_pinctrl = { ...@@ -414,7 +414,7 @@ static const struct msm_pinctrl_soc_data ipq4019_pinctrl = {
.nfunctions = ARRAY_SIZE(ipq4019_functions), .nfunctions = ARRAY_SIZE(ipq4019_functions),
.groups = ipq4019_groups, .groups = ipq4019_groups,
.ngroups = ARRAY_SIZE(ipq4019_groups), .ngroups = ARRAY_SIZE(ipq4019_groups),
.ngpios = 70, .ngpios = 100,
}; };
static int ipq4019_pinctrl_probe(struct platform_device *pdev) static int ipq4019_pinctrl_probe(struct platform_device *pdev)
......
...@@ -546,7 +546,9 @@ static int sh_pfc_probe(struct platform_device *pdev) ...@@ -546,7 +546,9 @@ static int sh_pfc_probe(struct platform_device *pdev)
return ret; return ret;
} }
pinctrl_provide_dummies(); /* Enable dummy states for those platforms without pinctrl support */
if (!of_have_populated_dt())
pinctrl_provide_dummies();
ret = sh_pfc_init_ranges(pfc); ret = sh_pfc_init_ranges(pfc);
if (ret < 0) if (ret < 0)
......
...@@ -485,6 +485,7 @@ static const struct sunxi_pinctrl_desc sun8i_a33_pinctrl_data = { ...@@ -485,6 +485,7 @@ static const struct sunxi_pinctrl_desc sun8i_a33_pinctrl_data = {
.pins = sun8i_a33_pins, .pins = sun8i_a33_pins,
.npins = ARRAY_SIZE(sun8i_a33_pins), .npins = ARRAY_SIZE(sun8i_a33_pins),
.irq_banks = 2, .irq_banks = 2,
.irq_bank_base = 1,
}; };
static int sun8i_a33_pinctrl_probe(struct platform_device *pdev) static int sun8i_a33_pinctrl_probe(struct platform_device *pdev)
......
...@@ -579,7 +579,7 @@ static void sunxi_pinctrl_irq_release_resources(struct irq_data *d) ...@@ -579,7 +579,7 @@ static void sunxi_pinctrl_irq_release_resources(struct irq_data *d)
static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type) static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
{ {
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
u32 reg = sunxi_irq_cfg_reg(d->hwirq); u32 reg = sunxi_irq_cfg_reg(d->hwirq, pctl->desc->irq_bank_base);
u8 index = sunxi_irq_cfg_offset(d->hwirq); u8 index = sunxi_irq_cfg_offset(d->hwirq);
unsigned long flags; unsigned long flags;
u32 regval; u32 regval;
...@@ -626,7 +626,8 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -626,7 +626,8 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
static void sunxi_pinctrl_irq_ack(struct irq_data *d) static void sunxi_pinctrl_irq_ack(struct irq_data *d)
{ {
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
u32 status_reg = sunxi_irq_status_reg(d->hwirq); u32 status_reg = sunxi_irq_status_reg(d->hwirq,
pctl->desc->irq_bank_base);
u8 status_idx = sunxi_irq_status_offset(d->hwirq); u8 status_idx = sunxi_irq_status_offset(d->hwirq);
/* Clear the IRQ */ /* Clear the IRQ */
...@@ -636,7 +637,7 @@ static void sunxi_pinctrl_irq_ack(struct irq_data *d) ...@@ -636,7 +637,7 @@ static void sunxi_pinctrl_irq_ack(struct irq_data *d)
static void sunxi_pinctrl_irq_mask(struct irq_data *d) static void sunxi_pinctrl_irq_mask(struct irq_data *d)
{ {
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
u32 reg = sunxi_irq_ctrl_reg(d->hwirq); u32 reg = sunxi_irq_ctrl_reg(d->hwirq, pctl->desc->irq_bank_base);
u8 idx = sunxi_irq_ctrl_offset(d->hwirq); u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
unsigned long flags; unsigned long flags;
u32 val; u32 val;
...@@ -653,7 +654,7 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d) ...@@ -653,7 +654,7 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d)
static void sunxi_pinctrl_irq_unmask(struct irq_data *d) static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
{ {
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
u32 reg = sunxi_irq_ctrl_reg(d->hwirq); u32 reg = sunxi_irq_ctrl_reg(d->hwirq, pctl->desc->irq_bank_base);
u8 idx = sunxi_irq_ctrl_offset(d->hwirq); u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
unsigned long flags; unsigned long flags;
u32 val; u32 val;
...@@ -745,7 +746,7 @@ static void sunxi_pinctrl_irq_handler(struct irq_desc *desc) ...@@ -745,7 +746,7 @@ static void sunxi_pinctrl_irq_handler(struct irq_desc *desc)
if (bank == pctl->desc->irq_banks) if (bank == pctl->desc->irq_banks)
return; return;
reg = sunxi_irq_status_reg_from_bank(bank); reg = sunxi_irq_status_reg_from_bank(bank, pctl->desc->irq_bank_base);
val = readl(pctl->membase + reg); val = readl(pctl->membase + reg);
if (val) { if (val) {
...@@ -1024,9 +1025,11 @@ int sunxi_pinctrl_init(struct platform_device *pdev, ...@@ -1024,9 +1025,11 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
for (i = 0; i < pctl->desc->irq_banks; i++) { for (i = 0; i < pctl->desc->irq_banks; i++) {
/* Mask and clear all IRQs before registering a handler */ /* Mask and clear all IRQs before registering a handler */
writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(i)); writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(i,
pctl->desc->irq_bank_base));
writel(0xffffffff, writel(0xffffffff,
pctl->membase + sunxi_irq_status_reg_from_bank(i)); pctl->membase + sunxi_irq_status_reg_from_bank(i,
pctl->desc->irq_bank_base));
irq_set_chained_handler_and_data(pctl->irq[i], irq_set_chained_handler_and_data(pctl->irq[i],
sunxi_pinctrl_irq_handler, sunxi_pinctrl_irq_handler,
......
...@@ -97,6 +97,7 @@ struct sunxi_pinctrl_desc { ...@@ -97,6 +97,7 @@ struct sunxi_pinctrl_desc {
int npins; int npins;
unsigned pin_base; unsigned pin_base;
unsigned irq_banks; unsigned irq_banks;
unsigned irq_bank_base;
bool irq_read_needs_mux; bool irq_read_needs_mux;
}; };
...@@ -233,12 +234,12 @@ static inline u32 sunxi_pull_offset(u16 pin) ...@@ -233,12 +234,12 @@ static inline u32 sunxi_pull_offset(u16 pin)
return pin_num * PULL_PINS_BITS; return pin_num * PULL_PINS_BITS;
} }
static inline u32 sunxi_irq_cfg_reg(u16 irq) static inline u32 sunxi_irq_cfg_reg(u16 irq, unsigned bank_base)
{ {
u8 bank = irq / IRQ_PER_BANK; u8 bank = irq / IRQ_PER_BANK;
u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04; u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
return IRQ_CFG_REG + bank * IRQ_MEM_SIZE + reg; return IRQ_CFG_REG + (bank_base + bank) * IRQ_MEM_SIZE + reg;
} }
static inline u32 sunxi_irq_cfg_offset(u16 irq) static inline u32 sunxi_irq_cfg_offset(u16 irq)
...@@ -247,16 +248,16 @@ static inline u32 sunxi_irq_cfg_offset(u16 irq) ...@@ -247,16 +248,16 @@ static inline u32 sunxi_irq_cfg_offset(u16 irq)
return irq_num * IRQ_CFG_IRQ_BITS; return irq_num * IRQ_CFG_IRQ_BITS;
} }
static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank) static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank, unsigned bank_base)
{ {
return IRQ_CTRL_REG + bank * IRQ_MEM_SIZE; return IRQ_CTRL_REG + (bank_base + bank) * IRQ_MEM_SIZE;
} }
static inline u32 sunxi_irq_ctrl_reg(u16 irq) static inline u32 sunxi_irq_ctrl_reg(u16 irq, unsigned bank_base)
{ {
u8 bank = irq / IRQ_PER_BANK; u8 bank = irq / IRQ_PER_BANK;
return sunxi_irq_ctrl_reg_from_bank(bank); return sunxi_irq_ctrl_reg_from_bank(bank, bank_base);
} }
static inline u32 sunxi_irq_ctrl_offset(u16 irq) static inline u32 sunxi_irq_ctrl_offset(u16 irq)
...@@ -265,16 +266,16 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq) ...@@ -265,16 +266,16 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq)
return irq_num * IRQ_CTRL_IRQ_BITS; return irq_num * IRQ_CTRL_IRQ_BITS;
} }
static inline u32 sunxi_irq_status_reg_from_bank(u8 bank) static inline u32 sunxi_irq_status_reg_from_bank(u8 bank, unsigned bank_base)
{ {
return IRQ_STATUS_REG + bank * IRQ_MEM_SIZE; return IRQ_STATUS_REG + (bank_base + bank) * IRQ_MEM_SIZE;
} }
static inline u32 sunxi_irq_status_reg(u16 irq) static inline u32 sunxi_irq_status_reg(u16 irq, unsigned bank_base)
{ {
u8 bank = irq / IRQ_PER_BANK; u8 bank = irq / IRQ_PER_BANK;
return sunxi_irq_status_reg_from_bank(bank); return sunxi_irq_status_reg_from_bank(bank, bank_base);
} }
static inline u32 sunxi_irq_status_offset(u16 irq) static inline u32 sunxi_irq_status_offset(u16 irq)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment