Commit 293428f9 authored by Andy Shevchenko's avatar Andy Shevchenko

pinctrl: cherryview: Re-use data structures from pinctrl-intel.h (part 3)

We have some data structures duplicated across the drivers.
Let's deduplicate them by using struct intel_pinctrl_soc_data,
struct intel_community and struct intel_pinctrl_context that
are being provided by pinctrl-intel.h.
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent c8f8f65e
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* /*
* Cherryview/Braswell pinctrl driver * Cherryview/Braswell pinctrl driver
* *
* Copyright (C) 2014, Intel Corporation * Copyright (C) 2014, 2020 Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com> * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
* *
* This driver is based on the original Cherryview GPIO driver by * This driver is based on the original Cherryview GPIO driver by
...@@ -67,35 +67,7 @@ ...@@ -67,35 +67,7 @@
#define CHV_PADCTRL1_INTWAKECFG_BOTH 3 #define CHV_PADCTRL1_INTWAKECFG_BOTH 3
#define CHV_PADCTRL1_INTWAKECFG_LEVEL 4 #define CHV_PADCTRL1_INTWAKECFG_LEVEL 4
/** struct intel_pad_context {
* struct chv_community - A community specific configuration
* @uid: ACPI _UID used to match the community
* @pins: All pins in this community
* @npins: Number of pins
* @groups: All groups in this community
* @ngroups: Number of groups
* @functions: All functions in this community
* @nfunctions: Number of functions
* @gpps: Pad groups
* @ngpps: Number of pad groups in this community
* @nirqs: Total number of IRQs this community can generate
* @acpi_space_id: An address space ID for ACPI OpRegion handler
*/
struct chv_community {
const char *uid;
const struct pinctrl_pin_desc *pins;
size_t npins;
const struct intel_pingroup *groups;
size_t ngroups;
const struct intel_function *functions;
size_t nfunctions;
const struct intel_padgroup *gpps;
size_t ngpps;
size_t nirqs;
acpi_adr_space_type acpi_space_id;
};
struct chv_pin_context {
u32 padctrl0; u32 padctrl0;
u32 padctrl1; u32 padctrl1;
}; };
...@@ -107,13 +79,13 @@ struct chv_pin_context { ...@@ -107,13 +79,13 @@ struct chv_pin_context {
* @pctldev: Pointer to the pin controller device * @pctldev: Pointer to the pin controller device
* @chip: GPIO chip in this pin controller * @chip: GPIO chip in this pin controller
* @irqchip: IRQ chip in this pin controller * @irqchip: IRQ chip in this pin controller
* @regs: MMIO registers * @soc: Community specific pin configuration data
* @communities: All communities in this pin controller
* @ncommunities: Number of communities in this pin controller
* @context: Configuration saved over system sleep
* @irq: Our parent irq * @irq: Our parent irq
* @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO * @intr_lines: Mapping between 16 HW interrupt wires and GPIO offset (in GPIO number space)
* offset (in GPIO number space)
* @community: Community this pinctrl instance represents
* @saved_intmask: Interrupt mask saved for system sleep * @saved_intmask: Interrupt mask saved for system sleep
* @saved_pin_context: Pointer to a context of the pins saved for system sleep
* *
* The first group in @groups is expected to contain all pins that can be * The first group in @groups is expected to contain all pins that can be
* used as GPIOs. * used as GPIOs.
...@@ -124,12 +96,14 @@ struct chv_pinctrl { ...@@ -124,12 +96,14 @@ struct chv_pinctrl {
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
struct gpio_chip chip; struct gpio_chip chip;
struct irq_chip irqchip; struct irq_chip irqchip;
void __iomem *regs; const struct intel_pinctrl_soc_data *soc;
unsigned int irq; struct intel_community *communities;
size_t ncommunities;
struct intel_pinctrl_context context;
int irq;
unsigned int intr_lines[16]; unsigned int intr_lines[16];
const struct chv_community *community;
u32 saved_intmask; u32 saved_intmask;
struct chv_pin_context *saved_pin_context;
}; };
#define PINMODE_INVERT_OE BIT(15) #define PINMODE_INVERT_OE BIT(15)
...@@ -142,6 +116,14 @@ struct chv_pinctrl { ...@@ -142,6 +116,14 @@ struct chv_pinctrl {
.size = (end) - (start) + 1, \ .size = (end) - (start) + 1, \
} }
#define CHV_COMMUNITY(g, i, a) \
{ \
.gpps = (g), \
.ngpps = ARRAY_SIZE(g), \
.nirqs = (i), \
.acpi_space_id = (a), \
}
static const struct pinctrl_pin_desc southwest_pins[] = { static const struct pinctrl_pin_desc southwest_pins[] = {
PINCTRL_PIN(0, "FST_SPI_D2"), PINCTRL_PIN(0, "FST_SPI_D2"),
PINCTRL_PIN(1, "FST_SPI_D0"), PINCTRL_PIN(1, "FST_SPI_D0"),
...@@ -303,7 +285,15 @@ static const struct intel_padgroup southwest_gpps[] = { ...@@ -303,7 +285,15 @@ static const struct intel_padgroup southwest_gpps[] = {
CHV_GPP(90, 97), CHV_GPP(90, 97),
}; };
static const struct chv_community southwest_community = { /*
* Southwest community can generate GPIO interrupts only for the first 8
* interrupts. The upper half (8-15) can only be used to trigger GPEs.
*/
static const struct intel_community southwest_communities[] = {
CHV_COMMUNITY(southwest_gpps, 8, 0x91),
};
static const struct intel_pinctrl_soc_data southwest_soc_data = {
.uid = "1", .uid = "1",
.pins = southwest_pins, .pins = southwest_pins,
.npins = ARRAY_SIZE(southwest_pins), .npins = ARRAY_SIZE(southwest_pins),
...@@ -311,15 +301,8 @@ static const struct chv_community southwest_community = { ...@@ -311,15 +301,8 @@ static const struct chv_community southwest_community = {
.ngroups = ARRAY_SIZE(southwest_groups), .ngroups = ARRAY_SIZE(southwest_groups),
.functions = southwest_functions, .functions = southwest_functions,
.nfunctions = ARRAY_SIZE(southwest_functions), .nfunctions = ARRAY_SIZE(southwest_functions),
.gpps = southwest_gpps, .communities = southwest_communities,
.ngpps = ARRAY_SIZE(southwest_gpps), .ncommunities = ARRAY_SIZE(southwest_communities),
/*
* Southwest community can generate GPIO interrupts only for the
* first 8 interrupts. The upper half (8-15) can only be used to
* trigger GPEs.
*/
.nirqs = 8,
.acpi_space_id = 0x91,
}; };
static const struct pinctrl_pin_desc north_pins[] = { static const struct pinctrl_pin_desc north_pins[] = {
...@@ -396,19 +379,20 @@ static const struct intel_padgroup north_gpps[] = { ...@@ -396,19 +379,20 @@ static const struct intel_padgroup north_gpps[] = {
CHV_GPP(60, 72), CHV_GPP(60, 72),
}; };
static const struct chv_community north_community = { /*
* North community can generate GPIO interrupts only for the first 8
* interrupts. The upper half (8-15) can only be used to trigger GPEs.
*/
static const struct intel_community north_communities[] = {
CHV_COMMUNITY(north_gpps, 8, 0x92),
};
static const struct intel_pinctrl_soc_data north_soc_data = {
.uid = "2", .uid = "2",
.pins = north_pins, .pins = north_pins,
.npins = ARRAY_SIZE(north_pins), .npins = ARRAY_SIZE(north_pins),
.gpps = north_gpps, .communities = north_communities,
.ngpps = ARRAY_SIZE(north_gpps), .ncommunities = ARRAY_SIZE(north_communities),
/*
* North community can generate GPIO interrupts only for the first
* 8 interrupts. The upper half (8-15) can only be used to trigger
* GPEs.
*/
.nirqs = 8,
.acpi_space_id = 0x92,
}; };
static const struct pinctrl_pin_desc east_pins[] = { static const struct pinctrl_pin_desc east_pins[] = {
...@@ -444,14 +428,16 @@ static const struct intel_padgroup east_gpps[] = { ...@@ -444,14 +428,16 @@ static const struct intel_padgroup east_gpps[] = {
CHV_GPP(15, 26), CHV_GPP(15, 26),
}; };
static const struct chv_community east_community = { static const struct intel_community east_communities[] = {
CHV_COMMUNITY(east_gpps, 16, 0x93),
};
static const struct intel_pinctrl_soc_data east_soc_data = {
.uid = "3", .uid = "3",
.pins = east_pins, .pins = east_pins,
.npins = ARRAY_SIZE(east_pins), .npins = ARRAY_SIZE(east_pins),
.gpps = east_gpps, .communities = east_communities,
.ngpps = ARRAY_SIZE(east_gpps), .ncommunities = ARRAY_SIZE(east_communities),
.nirqs = 16,
.acpi_space_id = 0x93,
}; };
static const struct pinctrl_pin_desc southeast_pins[] = { static const struct pinctrl_pin_desc southeast_pins[] = {
...@@ -566,7 +552,11 @@ static const struct intel_padgroup southeast_gpps[] = { ...@@ -566,7 +552,11 @@ static const struct intel_padgroup southeast_gpps[] = {
CHV_GPP(75, 85), CHV_GPP(75, 85),
}; };
static const struct chv_community southeast_community = { static const struct intel_community southeast_communities[] = {
CHV_COMMUNITY(southeast_gpps, 16, 0x94),
};
static const struct intel_pinctrl_soc_data southeast_soc_data = {
.uid = "4", .uid = "4",
.pins = southeast_pins, .pins = southeast_pins,
.npins = ARRAY_SIZE(southeast_pins), .npins = ARRAY_SIZE(southeast_pins),
...@@ -574,17 +564,16 @@ static const struct chv_community southeast_community = { ...@@ -574,17 +564,16 @@ static const struct chv_community southeast_community = {
.ngroups = ARRAY_SIZE(southeast_groups), .ngroups = ARRAY_SIZE(southeast_groups),
.functions = southeast_functions, .functions = southeast_functions,
.nfunctions = ARRAY_SIZE(southeast_functions), .nfunctions = ARRAY_SIZE(southeast_functions),
.gpps = southeast_gpps, .communities = southeast_communities,
.ngpps = ARRAY_SIZE(southeast_gpps), .ncommunities = ARRAY_SIZE(southeast_communities),
.nirqs = 16,
.acpi_space_id = 0x94,
}; };
static const struct chv_community *chv_communities[] = { static const struct intel_pinctrl_soc_data *chv_soc_data[] = {
&southwest_community, &southwest_soc_data,
&north_community, &north_soc_data,
&east_community, &east_soc_data,
&southeast_community, &southeast_soc_data,
NULL
}; };
/* /*
...@@ -600,12 +589,15 @@ static DEFINE_RAW_SPINLOCK(chv_lock); ...@@ -600,12 +589,15 @@ static DEFINE_RAW_SPINLOCK(chv_lock);
static u32 chv_pctrl_readl(struct chv_pinctrl *pctrl, unsigned int offset) static u32 chv_pctrl_readl(struct chv_pinctrl *pctrl, unsigned int offset)
{ {
return readl(pctrl->regs + offset); const struct intel_community *community = &pctrl->communities[0];
return readl(community->regs + offset);
} }
static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 value) static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 value)
{ {
void __iomem *reg = pctrl->regs + offset; const struct intel_community *community = &pctrl->communities[0];
void __iomem *reg = community->regs + offset;
/* Write and simple read back to confirm the bus transferring done */ /* Write and simple read back to confirm the bus transferring done */
writel(value, reg); writel(value, reg);
...@@ -615,13 +607,13 @@ static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 ...@@ -615,13 +607,13 @@ static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32
static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset, static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset,
unsigned int reg) unsigned int reg)
{ {
const struct intel_community *community = &pctrl->communities[0];
unsigned int family_no = offset / MAX_FAMILY_PAD_GPIO_NO; unsigned int family_no = offset / MAX_FAMILY_PAD_GPIO_NO;
unsigned int pad_no = offset % MAX_FAMILY_PAD_GPIO_NO; unsigned int pad_no = offset % MAX_FAMILY_PAD_GPIO_NO;
offset = FAMILY_PAD_REGS_OFF + FAMILY_PAD_REGS_SIZE * family_no + offset = FAMILY_PAD_REGS_SIZE * family_no + GPIO_REGS_SIZE * pad_no;
GPIO_REGS_SIZE * pad_no;
return pctrl->regs + offset + reg; return community->pad_regs + offset + reg;
} }
static u32 chv_readl(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset) static u32 chv_readl(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset)
...@@ -648,7 +640,7 @@ static int chv_get_groups_count(struct pinctrl_dev *pctldev) ...@@ -648,7 +640,7 @@ static int chv_get_groups_count(struct pinctrl_dev *pctldev)
{ {
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->community->ngroups; return pctrl->soc->ngroups;
} }
static const char *chv_get_group_name(struct pinctrl_dev *pctldev, static const char *chv_get_group_name(struct pinctrl_dev *pctldev,
...@@ -656,7 +648,7 @@ static const char *chv_get_group_name(struct pinctrl_dev *pctldev, ...@@ -656,7 +648,7 @@ static const char *chv_get_group_name(struct pinctrl_dev *pctldev,
{ {
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->community->groups[group].name; return pctrl->soc->groups[group].name;
} }
static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
...@@ -664,8 +656,8 @@ static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, ...@@ -664,8 +656,8 @@ static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
{ {
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
*pins = pctrl->community->groups[group].pins; *pins = pctrl->soc->groups[group].pins;
*npins = pctrl->community->groups[group].npins; *npins = pctrl->soc->groups[group].npins;
return 0; return 0;
} }
...@@ -713,7 +705,7 @@ static int chv_get_functions_count(struct pinctrl_dev *pctldev) ...@@ -713,7 +705,7 @@ static int chv_get_functions_count(struct pinctrl_dev *pctldev)
{ {
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->community->nfunctions; return pctrl->soc->nfunctions;
} }
static const char *chv_get_function_name(struct pinctrl_dev *pctldev, static const char *chv_get_function_name(struct pinctrl_dev *pctldev,
...@@ -721,7 +713,7 @@ static const char *chv_get_function_name(struct pinctrl_dev *pctldev, ...@@ -721,7 +713,7 @@ static const char *chv_get_function_name(struct pinctrl_dev *pctldev,
{ {
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->community->functions[function].name; return pctrl->soc->functions[function].name;
} }
static int chv_get_function_groups(struct pinctrl_dev *pctldev, static int chv_get_function_groups(struct pinctrl_dev *pctldev,
...@@ -731,8 +723,8 @@ static int chv_get_function_groups(struct pinctrl_dev *pctldev, ...@@ -731,8 +723,8 @@ static int chv_get_function_groups(struct pinctrl_dev *pctldev,
{ {
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
*groups = pctrl->community->functions[function].groups; *groups = pctrl->soc->functions[function].groups;
*ngroups = pctrl->community->functions[function].ngroups; *ngroups = pctrl->soc->functions[function].ngroups;
return 0; return 0;
} }
...@@ -744,7 +736,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, ...@@ -744,7 +736,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned long flags; unsigned long flags;
int i; int i;
grp = &pctrl->community->groups[group]; grp = &pctrl->soc->groups[group];
raw_spin_lock_irqsave(&chv_lock, flags); raw_spin_lock_irqsave(&chv_lock, flags);
...@@ -1412,6 +1404,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) ...@@ -1412,6 +1404,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc)
{ {
struct gpio_chip *gc = irq_desc_get_handler_data(desc); struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct chv_pinctrl *pctrl = gpiochip_get_data(gc); struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
const struct intel_community *community = &pctrl->communities[0];
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned long pending; unsigned long pending;
unsigned long flags; unsigned long flags;
...@@ -1423,7 +1416,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) ...@@ -1423,7 +1416,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc)
pending = chv_pctrl_readl(pctrl, CHV_INTSTAT); pending = chv_pctrl_readl(pctrl, CHV_INTSTAT);
raw_spin_unlock_irqrestore(&chv_lock, flags); raw_spin_unlock_irqrestore(&chv_lock, flags);
for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) { for_each_set_bit(intr_line, &pending, community->nirqs) {
unsigned int irq, offset; unsigned int irq, offset;
offset = pctrl->intr_lines[intr_line]; offset = pctrl->intr_lines[intr_line];
...@@ -1480,15 +1473,15 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, ...@@ -1480,15 +1473,15 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip,
unsigned int ngpios) unsigned int ngpios)
{ {
struct chv_pinctrl *pctrl = gpiochip_get_data(chip); struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
const struct chv_community *community = pctrl->community; const struct intel_community *community = &pctrl->communities[0];
int i; int i;
/* Do not add GPIOs that can only generate GPEs to the IRQ domain */ /* Do not add GPIOs that can only generate GPEs to the IRQ domain */
for (i = 0; i < community->npins; i++) { for (i = 0; i < pctrl->soc->npins; i++) {
const struct pinctrl_pin_desc *desc; const struct pinctrl_pin_desc *desc;
u32 intsel; u32 intsel;
desc = &community->pins[i]; desc = &pctrl->soc->pins[i];
intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0); intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0);
intsel &= CHV_PADCTRL0_INTSEL_MASK; intsel &= CHV_PADCTRL0_INTSEL_MASK;
...@@ -1502,6 +1495,7 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, ...@@ -1502,6 +1495,7 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip,
static int chv_gpio_irq_init_hw(struct gpio_chip *chip) static int chv_gpio_irq_init_hw(struct gpio_chip *chip)
{ {
struct chv_pinctrl *pctrl = gpiochip_get_data(chip); struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
const struct intel_community *community = &pctrl->communities[0];
/* /*
* The same set of machines in chv_no_valid_mask[] have incorrectly * The same set of machines in chv_no_valid_mask[] have incorrectly
...@@ -1515,7 +1509,7 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip) ...@@ -1515,7 +1509,7 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip)
* Mask all interrupts the community is able to generate * Mask all interrupts the community is able to generate
* but leave the ones that can only generate GPEs unmasked. * but leave the ones that can only generate GPEs unmasked.
*/ */
chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, pctrl->community->nirqs)); chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, community->nirqs));
} }
/* Clear all interrupts */ /* Clear all interrupts */
...@@ -1527,7 +1521,7 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip) ...@@ -1527,7 +1521,7 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip)
static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) static int chv_gpio_add_pin_ranges(struct gpio_chip *chip)
{ {
struct chv_pinctrl *pctrl = gpiochip_get_data(chip); struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
const struct chv_community *community = pctrl->community; const struct intel_community *community = &pctrl->communities[0];
const struct intel_padgroup *gpp; const struct intel_padgroup *gpp;
int ret, i; int ret, i;
...@@ -1547,15 +1541,15 @@ static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) ...@@ -1547,15 +1541,15 @@ static int chv_gpio_add_pin_ranges(struct gpio_chip *chip)
static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
{ {
const struct intel_community *community = &pctrl->communities[0];
const struct intel_padgroup *gpp; const struct intel_padgroup *gpp;
struct gpio_chip *chip = &pctrl->chip; struct gpio_chip *chip = &pctrl->chip;
bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); bool need_valid_mask = !dmi_check_system(chv_no_valid_mask);
const struct chv_community *community = pctrl->community;
int ret, i, irq_base; int ret, i, irq_base;
*chip = chv_gpio_chip; *chip = chv_gpio_chip;
chip->ngpio = community->pins[community->npins - 1].number + 1; chip->ngpio = pctrl->soc->pins[pctrl->soc->npins - 1].number + 1;
chip->label = dev_name(pctrl->dev); chip->label = dev_name(pctrl->dev);
chip->add_pin_ranges = chv_gpio_add_pin_ranges; chip->add_pin_ranges = chv_gpio_add_pin_ranges;
chip->parent = pctrl->dev; chip->parent = pctrl->dev;
...@@ -1581,7 +1575,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) ...@@ -1581,7 +1575,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
chip->irq.init_valid_mask = chv_init_irq_valid_mask; chip->irq.init_valid_mask = chv_init_irq_valid_mask;
} else { } else {
irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0,
community->npins, NUMA_NO_NODE); pctrl->soc->npins, NUMA_NO_NODE);
if (irq_base < 0) { if (irq_base < 0) {
dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n");
return irq_base; return irq_base;
...@@ -1631,6 +1625,10 @@ static acpi_status chv_pinctrl_mmio_access_handler(u32 function, ...@@ -1631,6 +1625,10 @@ static acpi_status chv_pinctrl_mmio_access_handler(u32 function,
static int chv_pinctrl_probe(struct platform_device *pdev) static int chv_pinctrl_probe(struct platform_device *pdev)
{ {
const struct intel_pinctrl_soc_data *soc_data = NULL;
const struct intel_pinctrl_soc_data **soc_table;
struct intel_community *community;
struct device *dev = &pdev->dev;
struct chv_pinctrl *pctrl; struct chv_pinctrl *pctrl;
struct acpi_device *adev; struct acpi_device *adev;
acpi_status status; acpi_status status;
...@@ -1640,40 +1638,53 @@ static int chv_pinctrl_probe(struct platform_device *pdev) ...@@ -1640,40 +1638,53 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
if (!adev) if (!adev)
return -ENODEV; return -ENODEV;
pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(dev);
if (!pctrl) for (i = 0; soc_table[i]; i++) {
return -ENOMEM; if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
soc_data = soc_table[i];
for (i = 0; i < ARRAY_SIZE(chv_communities); i++)
if (!strcmp(adev->pnp.unique_id, chv_communities[i]->uid)) {
pctrl->community = chv_communities[i];
break; break;
} }
if (i == ARRAY_SIZE(chv_communities)) }
if (!soc_data)
return -ENODEV; return -ENODEV;
pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
return -ENOMEM;
pctrl->dev = &pdev->dev; pctrl->dev = &pdev->dev;
pctrl->soc = soc_data;
pctrl->ncommunities = pctrl->soc->ncommunities;
pctrl->communities = devm_kmemdup(dev, pctrl->soc->communities,
pctrl->ncommunities * sizeof(*pctrl->communities),
GFP_KERNEL);
if (!pctrl->communities)
return -ENOMEM;
community = &pctrl->communities[0];
community->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(community->regs))
return PTR_ERR(community->regs);
community->pad_regs = community->regs + FAMILY_PAD_REGS_OFF;
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
pctrl->saved_pin_context = devm_kcalloc(pctrl->dev, pctrl->context.pads = devm_kcalloc(dev, pctrl->soc->npins,
pctrl->community->npins, sizeof(*pctrl->saved_pin_context), sizeof(*pctrl->context.pads),
GFP_KERNEL); GFP_KERNEL);
if (!pctrl->saved_pin_context) if (!pctrl->context.pads)
return -ENOMEM; return -ENOMEM;
#endif #endif
pctrl->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctrl->regs))
return PTR_ERR(pctrl->regs);
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) if (irq < 0)
return irq; return irq;
pctrl->pctldesc = chv_pinctrl_desc; pctrl->pctldesc = chv_pinctrl_desc;
pctrl->pctldesc.name = dev_name(&pdev->dev); pctrl->pctldesc.name = dev_name(&pdev->dev);
pctrl->pctldesc.pins = pctrl->community->pins; pctrl->pctldesc.pins = pctrl->soc->pins;
pctrl->pctldesc.npins = pctrl->community->npins; pctrl->pctldesc.npins = pctrl->soc->npins;
pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc, pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc,
pctrl); pctrl);
...@@ -1687,7 +1698,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev) ...@@ -1687,7 +1698,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
return ret; return ret;
status = acpi_install_address_space_handler(adev->handle, status = acpi_install_address_space_handler(adev->handle,
pctrl->community->acpi_space_id, community->acpi_space_id,
chv_pinctrl_mmio_access_handler, chv_pinctrl_mmio_access_handler,
NULL, pctrl); NULL, pctrl);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
...@@ -1701,9 +1712,10 @@ static int chv_pinctrl_probe(struct platform_device *pdev) ...@@ -1701,9 +1712,10 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
static int chv_pinctrl_remove(struct platform_device *pdev) static int chv_pinctrl_remove(struct platform_device *pdev)
{ {
struct chv_pinctrl *pctrl = platform_get_drvdata(pdev); struct chv_pinctrl *pctrl = platform_get_drvdata(pdev);
const struct intel_community *community = &pctrl->communities[0];
acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev), acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev),
pctrl->community->acpi_space_id, community->acpi_space_id,
chv_pinctrl_mmio_access_handler); chv_pinctrl_mmio_access_handler);
return 0; return 0;
...@@ -1720,16 +1732,14 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) ...@@ -1720,16 +1732,14 @@ static int chv_pinctrl_suspend_noirq(struct device *dev)
pctrl->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); pctrl->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK);
for (i = 0; i < pctrl->community->npins; i++) { for (i = 0; i < pctrl->soc->npins; i++) {
const struct pinctrl_pin_desc *desc; const struct pinctrl_pin_desc *desc;
struct chv_pin_context *ctx; struct intel_pad_context *ctx = &pctrl->context.pads[i];
desc = &pctrl->community->pins[i]; desc = &pctrl->soc->pins[i];
if (chv_pad_locked(pctrl, desc->number)) if (chv_pad_locked(pctrl, desc->number))
continue; continue;
ctx = &pctrl->saved_pin_context[i];
ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0); ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0);
ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE; ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE;
...@@ -1756,17 +1766,15 @@ static int chv_pinctrl_resume_noirq(struct device *dev) ...@@ -1756,17 +1766,15 @@ static int chv_pinctrl_resume_noirq(struct device *dev)
*/ */
chv_pctrl_writel(pctrl, CHV_INTMASK, 0x0000); chv_pctrl_writel(pctrl, CHV_INTMASK, 0x0000);
for (i = 0; i < pctrl->community->npins; i++) { for (i = 0; i < pctrl->soc->npins; i++) {
const struct pinctrl_pin_desc *desc; const struct pinctrl_pin_desc *desc;
const struct chv_pin_context *ctx; struct intel_pad_context *ctx = &pctrl->context.pads[i];
u32 val; u32 val;
desc = &pctrl->community->pins[i]; desc = &pctrl->soc->pins[i];
if (chv_pad_locked(pctrl, desc->number)) if (chv_pad_locked(pctrl, desc->number))
continue; continue;
ctx = &pctrl->saved_pin_context[i];
/* Only restore if our saved state differs from the current */ /* Only restore if our saved state differs from the current */
val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); val = chv_readl(pctrl, desc->number, CHV_PADCTRL0);
val &= ~CHV_PADCTRL0_GPIORXSTATE; val &= ~CHV_PADCTRL0_GPIORXSTATE;
...@@ -1803,7 +1811,7 @@ static const struct dev_pm_ops chv_pinctrl_pm_ops = { ...@@ -1803,7 +1811,7 @@ static const struct dev_pm_ops chv_pinctrl_pm_ops = {
}; };
static const struct acpi_device_id chv_pinctrl_acpi_match[] = { static const struct acpi_device_id chv_pinctrl_acpi_match[] = {
{ "INT33FF" }, { "INT33FF", (kernel_ulong_t)chv_soc_data },
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match); MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match);
......
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