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

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
Loading
Loading
Loading
Loading
+137 −129
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
/*
 * Cherryview/Braswell pinctrl driver
 *
 * Copyright (C) 2014, Intel Corporation
 * Copyright (C) 2014, 2020 Intel Corporation
 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
 *
 * This driver is based on the original Cherryview GPIO driver by
@@ -67,35 +67,7 @@
#define CHV_PADCTRL1_INTWAKECFG_BOTH	3
#define CHV_PADCTRL1_INTWAKECFG_LEVEL	4

/**
 * 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 {
struct intel_pad_context {
	u32 padctrl0;
	u32 padctrl1;
};
@@ -107,13 +79,13 @@ struct chv_pin_context {
 * @pctldev: Pointer to the pin controller device
 * @chip: GPIO 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
 * @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO
 *		offset (in GPIO number space)
 * @community: Community this pinctrl instance represents
 * @intr_lines: Mapping between 16 HW interrupt wires and GPIO offset (in GPIO number space)
 * @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
 * used as GPIOs.
@@ -124,12 +96,14 @@ struct chv_pinctrl {
	struct pinctrl_dev *pctldev;
	struct gpio_chip chip;
	struct irq_chip irqchip;
	void __iomem *regs;
	unsigned int irq;
	const struct intel_pinctrl_soc_data *soc;
	struct intel_community *communities;
	size_t ncommunities;
	struct intel_pinctrl_context context;
	int irq;

	unsigned int intr_lines[16];
	const struct chv_community *community;
	u32 saved_intmask;
	struct chv_pin_context *saved_pin_context;
};

#define	PINMODE_INVERT_OE	BIT(15)
@@ -142,6 +116,14 @@ struct chv_pinctrl {
		.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[] = {
	PINCTRL_PIN(0, "FST_SPI_D2"),
	PINCTRL_PIN(1, "FST_SPI_D0"),
@@ -303,7 +285,15 @@ static const struct intel_padgroup southwest_gpps[] = {
	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",
	.pins = southwest_pins,
	.npins = ARRAY_SIZE(southwest_pins),
@@ -311,15 +301,8 @@ static const struct chv_community southwest_community = {
	.ngroups = ARRAY_SIZE(southwest_groups),
	.functions = southwest_functions,
	.nfunctions = ARRAY_SIZE(southwest_functions),
	.gpps = southwest_gpps,
	.ngpps = ARRAY_SIZE(southwest_gpps),
	/*
	 * 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,
	.communities = southwest_communities,
	.ncommunities = ARRAY_SIZE(southwest_communities),
};

static const struct pinctrl_pin_desc north_pins[] = {
@@ -396,19 +379,20 @@ static const struct intel_padgroup north_gpps[] = {
	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",
	.pins = north_pins,
	.npins = ARRAY_SIZE(north_pins),
	.gpps = north_gpps,
	.ngpps = ARRAY_SIZE(north_gpps),
	/*
	 * 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,
	.communities = north_communities,
	.ncommunities = ARRAY_SIZE(north_communities),
};

static const struct pinctrl_pin_desc east_pins[] = {
@@ -444,14 +428,16 @@ static const struct intel_padgroup east_gpps[] = {
	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",
	.pins = east_pins,
	.npins = ARRAY_SIZE(east_pins),
	.gpps = east_gpps,
	.ngpps = ARRAY_SIZE(east_gpps),
	.nirqs = 16,
	.acpi_space_id = 0x93,
	.communities = east_communities,
	.ncommunities = ARRAY_SIZE(east_communities),
};

static const struct pinctrl_pin_desc southeast_pins[] = {
@@ -566,7 +552,11 @@ static const struct intel_padgroup southeast_gpps[] = {
	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",
	.pins = southeast_pins,
	.npins = ARRAY_SIZE(southeast_pins),
@@ -574,17 +564,16 @@ static const struct chv_community southeast_community = {
	.ngroups = ARRAY_SIZE(southeast_groups),
	.functions = southeast_functions,
	.nfunctions = ARRAY_SIZE(southeast_functions),
	.gpps = southeast_gpps,
	.ngpps = ARRAY_SIZE(southeast_gpps),
	.nirqs = 16,
	.acpi_space_id = 0x94,
	.communities = southeast_communities,
	.ncommunities = ARRAY_SIZE(southeast_communities),
};

static const struct chv_community *chv_communities[] = {
	&southwest_community,
	&north_community,
	&east_community,
	&southeast_community,
static const struct intel_pinctrl_soc_data *chv_soc_data[] = {
	&southwest_soc_data,
	&north_soc_data,
	&east_soc_data,
	&southeast_soc_data,
	NULL
};

/*
@@ -600,12 +589,15 @@ static DEFINE_RAW_SPINLOCK(chv_lock);

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)
{
	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 */
	writel(value, reg);
@@ -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,
				unsigned int reg)
{
	const struct intel_community *community = &pctrl->communities[0];
	unsigned int family_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 +
		 GPIO_REGS_SIZE * pad_no;
	offset = FAMILY_PAD_REGS_SIZE * family_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)
@@ -648,7 +640,7 @@ static int chv_get_groups_count(struct pinctrl_dev *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,
@@ -656,7 +648,7 @@ static const char *chv_get_group_name(struct pinctrl_dev *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,
@@ -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);

	*pins = pctrl->community->groups[group].pins;
	*npins = pctrl->community->groups[group].npins;
	*pins = pctrl->soc->groups[group].pins;
	*npins = pctrl->soc->groups[group].npins;
	return 0;
}

@@ -713,7 +705,7 @@ static int chv_get_functions_count(struct pinctrl_dev *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,
@@ -721,7 +713,7 @@ static const char *chv_get_function_name(struct pinctrl_dev *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,
@@ -731,8 +723,8 @@ static int chv_get_function_groups(struct pinctrl_dev *pctldev,
{
	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);

	*groups = pctrl->community->functions[function].groups;
	*ngroups = pctrl->community->functions[function].ngroups;
	*groups = pctrl->soc->functions[function].groups;
	*ngroups = pctrl->soc->functions[function].ngroups;
	return 0;
}

@@ -744,7 +736,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev,
	unsigned long flags;
	int i;

	grp = &pctrl->community->groups[group];
	grp = &pctrl->soc->groups[group];

	raw_spin_lock_irqsave(&chv_lock, flags);

@@ -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 chv_pinctrl *pctrl = gpiochip_get_data(gc);
	const struct intel_community *community = &pctrl->communities[0];
	struct irq_chip *chip = irq_desc_get_chip(desc);
	unsigned long pending;
	unsigned long flags;
@@ -1423,7 +1416,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc)
	pending = chv_pctrl_readl(pctrl, CHV_INTSTAT);
	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;

		offset = pctrl->intr_lines[intr_line];
@@ -1480,15 +1473,15 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip,
				    unsigned int ngpios)
{
	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;

	/* 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;
		u32 intsel;

		desc = &community->pins[i];
		desc = &pctrl->soc->pins[i];

		intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0);
		intsel &= CHV_PADCTRL0_INTSEL_MASK;
@@ -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)
{
	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
@@ -1515,7 +1509,7 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip)
		 * Mask all interrupts the community is able to generate
		 * 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 */
@@ -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)
{
	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;
	int ret, i;

@@ -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)
{
	const struct intel_community *community = &pctrl->communities[0];
	const struct intel_padgroup *gpp;
	struct gpio_chip *chip = &pctrl->chip;
	bool need_valid_mask = !dmi_check_system(chv_no_valid_mask);
	const struct chv_community *community = pctrl->community;
	int ret, i, irq_base;

	*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->add_pin_ranges = chv_gpio_add_pin_ranges;
	chip->parent = pctrl->dev;
@@ -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;
	} else {
		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) {
			dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n");
			return irq_base;
@@ -1631,6 +1625,10 @@ static acpi_status chv_pinctrl_mmio_access_handler(u32 function,

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 acpi_device *adev;
	acpi_status status;
@@ -1640,40 +1638,53 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
	if (!adev)
		return -ENODEV;

	pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
	if (!pctrl)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(chv_communities); i++)
		if (!strcmp(adev->pnp.unique_id, chv_communities[i]->uid)) {
			pctrl->community = chv_communities[i];
	soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(dev);
	for (i = 0; soc_table[i]; i++) {
		if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
			soc_data = soc_table[i];
			break;
		}
	if (i == ARRAY_SIZE(chv_communities))
	}
	if (!soc_data)
		return -ENODEV;

	pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
	if (!pctrl)
		return -ENOMEM;

	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
	pctrl->saved_pin_context = devm_kcalloc(pctrl->dev,
		pctrl->community->npins, sizeof(*pctrl->saved_pin_context),
	pctrl->context.pads = devm_kcalloc(dev, pctrl->soc->npins,
					   sizeof(*pctrl->context.pads),
					   GFP_KERNEL);
	if (!pctrl->saved_pin_context)
	if (!pctrl->context.pads)
		return -ENOMEM;
#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);
	if (irq < 0)
		return irq;

	pctrl->pctldesc = chv_pinctrl_desc;
	pctrl->pctldesc.name = dev_name(&pdev->dev);
	pctrl->pctldesc.pins = pctrl->community->pins;
	pctrl->pctldesc.npins = pctrl->community->npins;
	pctrl->pctldesc.pins = pctrl->soc->pins;
	pctrl->pctldesc.npins = pctrl->soc->npins;

	pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc,
					       pctrl);
@@ -1687,7 +1698,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
		return ret;

	status = acpi_install_address_space_handler(adev->handle,
					pctrl->community->acpi_space_id,
					community->acpi_space_id,
					chv_pinctrl_mmio_access_handler,
					NULL, pctrl);
	if (ACPI_FAILURE(status))
@@ -1701,9 +1712,10 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
static int chv_pinctrl_remove(struct platform_device *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),
					  pctrl->community->acpi_space_id,
					  community->acpi_space_id,
					  chv_pinctrl_mmio_access_handler);

	return 0;
@@ -1720,16 +1732,14 @@ static int chv_pinctrl_suspend_noirq(struct device *dev)

	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;
		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))
			continue;

		ctx = &pctrl->saved_pin_context[i];

		ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0);
		ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE;

@@ -1756,17 +1766,15 @@ static int chv_pinctrl_resume_noirq(struct device *dev)
	 */
	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 chv_pin_context *ctx;
		struct intel_pad_context *ctx = &pctrl->context.pads[i];
		u32 val;

		desc = &pctrl->community->pins[i];
		desc = &pctrl->soc->pins[i];
		if (chv_pad_locked(pctrl, desc->number))
			continue;

		ctx = &pctrl->saved_pin_context[i];

		/* Only restore if our saved state differs from the current */
		val = chv_readl(pctrl, desc->number, CHV_PADCTRL0);
		val &= ~CHV_PADCTRL0_GPIORXSTATE;
@@ -1803,7 +1811,7 @@ static const struct dev_pm_ops chv_pinctrl_pm_ops = {
};

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);