mirror of
https://github.com/torvalds/linux.git
synced 2024-11-13 07:31:45 +00:00
pinctrl: intel: fix bug of register offset calculation
The group size for registers PADCFGLOCK, HOSTSW_OWN, GPI_IS, GPI_IE, are not 24 for Broxton, Add a parameter to allow different platform to set correct value. Signed-off-by: Qi Zheng <qi.zheng@intel.com> Signed-off-by: Qipeng Zha <qipeng.zha@intel.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
46435d4c35
commit
618a919b4c
@ -28,6 +28,7 @@
|
|||||||
.padcfglock_offset = BXT_PADCFGLOCK, \
|
.padcfglock_offset = BXT_PADCFGLOCK, \
|
||||||
.hostown_offset = BXT_HOSTSW_OWN, \
|
.hostown_offset = BXT_HOSTSW_OWN, \
|
||||||
.ie_offset = BXT_GPI_IE, \
|
.ie_offset = BXT_GPI_IE, \
|
||||||
|
.gpp_size = 32, \
|
||||||
.pin_base = (s), \
|
.pin_base = (s), \
|
||||||
.npins = ((e) - (s) + 1), \
|
.npins = ((e) - (s) + 1), \
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "pinctrl-intel.h"
|
#include "pinctrl-intel.h"
|
||||||
|
|
||||||
/* Maximum number of pads in each group */
|
|
||||||
#define NPADS_IN_GPP 24
|
|
||||||
|
|
||||||
/* Offset from regs */
|
/* Offset from regs */
|
||||||
#define PADBAR 0x00c
|
#define PADBAR 0x00c
|
||||||
#define GPI_IS 0x100
|
#define GPI_IS 0x100
|
||||||
@ -173,11 +170,11 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned pin)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
padno = pin_to_padno(community, pin);
|
padno = pin_to_padno(community, pin);
|
||||||
gpp = padno / NPADS_IN_GPP;
|
gpp = padno / community->gpp_size;
|
||||||
offset = community->hostown_offset + gpp * 4;
|
offset = community->hostown_offset + gpp * 4;
|
||||||
hostown = community->regs + offset;
|
hostown = community->regs + offset;
|
||||||
|
|
||||||
return !(readl(hostown) & BIT(padno % NPADS_IN_GPP));
|
return !(readl(hostown) & BIT(padno % community->gpp_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
|
static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
|
||||||
@ -193,7 +190,7 @@ static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
padno = pin_to_padno(community, pin);
|
padno = pin_to_padno(community, pin);
|
||||||
gpp = padno / NPADS_IN_GPP;
|
gpp = padno / community->gpp_size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
|
* If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
|
||||||
@ -202,12 +199,12 @@ static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
|
|||||||
*/
|
*/
|
||||||
offset = community->padcfglock_offset + gpp * 8;
|
offset = community->padcfglock_offset + gpp * 8;
|
||||||
value = readl(community->regs + offset);
|
value = readl(community->regs + offset);
|
||||||
if (value & BIT(pin % NPADS_IN_GPP))
|
if (value & BIT(pin % community->gpp_size))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
offset = community->padcfglock_offset + 4 + gpp * 8;
|
offset = community->padcfglock_offset + 4 + gpp * 8;
|
||||||
value = readl(community->regs + offset);
|
value = readl(community->regs + offset);
|
||||||
if (value & BIT(pin % NPADS_IN_GPP))
|
if (value & BIT(pin % community->gpp_size))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -663,8 +660,8 @@ static void intel_gpio_irq_ack(struct irq_data *d)
|
|||||||
community = intel_get_community(pctrl, pin);
|
community = intel_get_community(pctrl, pin);
|
||||||
if (community) {
|
if (community) {
|
||||||
unsigned padno = pin_to_padno(community, pin);
|
unsigned padno = pin_to_padno(community, pin);
|
||||||
unsigned gpp_offset = padno % NPADS_IN_GPP;
|
unsigned gpp_offset = padno % community->gpp_size;
|
||||||
unsigned gpp = padno / NPADS_IN_GPP;
|
unsigned gpp = padno / community->gpp_size;
|
||||||
|
|
||||||
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
|
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
|
||||||
}
|
}
|
||||||
@ -685,8 +682,8 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
|||||||
community = intel_get_community(pctrl, pin);
|
community = intel_get_community(pctrl, pin);
|
||||||
if (community) {
|
if (community) {
|
||||||
unsigned padno = pin_to_padno(community, pin);
|
unsigned padno = pin_to_padno(community, pin);
|
||||||
unsigned gpp_offset = padno % NPADS_IN_GPP;
|
unsigned gpp_offset = padno % community->gpp_size;
|
||||||
unsigned gpp = padno / NPADS_IN_GPP;
|
unsigned gpp = padno / community->gpp_size;
|
||||||
void __iomem *reg;
|
void __iomem *reg;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
@ -780,8 +777,8 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
padno = pin_to_padno(community, pin);
|
padno = pin_to_padno(community, pin);
|
||||||
gpp = padno / NPADS_IN_GPP;
|
gpp = padno / community->gpp_size;
|
||||||
gpp_offset = padno % NPADS_IN_GPP;
|
gpp_offset = padno % community->gpp_size;
|
||||||
|
|
||||||
/* Clear the existing wake status */
|
/* Clear the existing wake status */
|
||||||
writel(BIT(gpp_offset), community->regs + GPI_GPE_STS + gpp * 4);
|
writel(BIT(gpp_offset), community->regs + GPI_GPE_STS + gpp * 4);
|
||||||
@ -819,14 +816,14 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
|
|||||||
/* Only interrupts that are enabled */
|
/* Only interrupts that are enabled */
|
||||||
pending &= enabled;
|
pending &= enabled;
|
||||||
|
|
||||||
for_each_set_bit(gpp_offset, &pending, NPADS_IN_GPP) {
|
for_each_set_bit(gpp_offset, &pending, community->gpp_size) {
|
||||||
unsigned padno, irq;
|
unsigned padno, irq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The last group in community can have less pins
|
* The last group in community can have less pins
|
||||||
* than NPADS_IN_GPP.
|
* than NPADS_IN_GPP.
|
||||||
*/
|
*/
|
||||||
padno = gpp_offset + gpp * NPADS_IN_GPP;
|
padno = gpp_offset + gpp * community->gpp_size;
|
||||||
if (padno >= community->npins)
|
if (padno >= community->npins)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1002,7 +999,8 @@ int intel_pinctrl_probe(struct platform_device *pdev,
|
|||||||
|
|
||||||
community->regs = regs;
|
community->regs = regs;
|
||||||
community->pad_regs = regs + padbar;
|
community->pad_regs = regs + padbar;
|
||||||
community->ngpps = DIV_ROUND_UP(community->npins, NPADS_IN_GPP);
|
community->ngpps = DIV_ROUND_UP(community->npins,
|
||||||
|
community->gpp_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
|
@ -55,6 +55,8 @@ struct intel_function {
|
|||||||
* ACPI).
|
* ACPI).
|
||||||
* @ie_offset: Register offset of GPI_IE from @regs.
|
* @ie_offset: Register offset of GPI_IE from @regs.
|
||||||
* @pin_base: Starting pin of pins in this community
|
* @pin_base: Starting pin of pins in this community
|
||||||
|
* @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK,
|
||||||
|
* HOSTSW_OWN, GPI_IS, GPI_IE, etc.
|
||||||
* @npins: Number of pins in this community
|
* @npins: Number of pins in this community
|
||||||
* @regs: Community specific common registers (reserved for core driver)
|
* @regs: Community specific common registers (reserved for core driver)
|
||||||
* @pad_regs: Community specific pad registers (reserved for core driver)
|
* @pad_regs: Community specific pad registers (reserved for core driver)
|
||||||
@ -68,6 +70,7 @@ struct intel_community {
|
|||||||
unsigned hostown_offset;
|
unsigned hostown_offset;
|
||||||
unsigned ie_offset;
|
unsigned ie_offset;
|
||||||
unsigned pin_base;
|
unsigned pin_base;
|
||||||
|
unsigned gpp_size;
|
||||||
size_t npins;
|
size_t npins;
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
void __iomem *pad_regs;
|
void __iomem *pad_regs;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
.padcfglock_offset = SPT_PADCFGLOCK, \
|
.padcfglock_offset = SPT_PADCFGLOCK, \
|
||||||
.hostown_offset = SPT_HOSTSW_OWN, \
|
.hostown_offset = SPT_HOSTSW_OWN, \
|
||||||
.ie_offset = SPT_GPI_IE, \
|
.ie_offset = SPT_GPI_IE, \
|
||||||
|
.gpp_size = 24, \
|
||||||
.pin_base = (s), \
|
.pin_base = (s), \
|
||||||
.npins = ((e) - (s) + 1), \
|
.npins = ((e) - (s) + 1), \
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user