Commit 40075341 authored by Linus Walleij's avatar Linus Walleij
Browse files

Merge tag 'intel-pinctrl-v5.12-1' of...

Merge tag 'intel-pinctrl-v5.12-1' of gitolite.kernel.org:pub/scm/linux/kernel/git/pinctrl/intel into devel

intel-pinctrl for v5.12-1

* Enable pin control on Intel Alder Lake-P
* Traverse through capabilities, convert them to features for the future use

The following is an automated git shortlog grouped by driver:

intel:
 -  Convert capability list to features
 -  Drop unnecessary check for predefined features
 -  Split intel_pinctrl_add_padgroups() for better maintenance

tigerlake:
 -  Add Alder Lake-P ACPI ID
parents b4478a08 0e793a4e
Loading
Loading
Loading
Loading
+83 −34
Original line number Diff line number Diff line
@@ -29,6 +29,16 @@
#define REVID_SHIFT			16
#define REVID_MASK			GENMASK(31, 16)

#define CAPLIST				0x004
#define CAPLIST_ID_SHIFT		16
#define CAPLIST_ID_MASK			GENMASK(23, 16)
#define CAPLIST_ID_GPIO_HW_INFO		1
#define CAPLIST_ID_PWM			2
#define CAPLIST_ID_BLINK		3
#define CAPLIST_ID_EXP			4
#define CAPLIST_NEXT_SHIFT		0
#define CAPLIST_NEXT_MASK		GENMASK(15, 0)

#define PADBAR				0x00c

#define PADOWN_BITS			4
@@ -1321,34 +1331,19 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
	return 0;
}

static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
static int intel_pinctrl_add_padgroups_by_gpps(struct intel_pinctrl *pctrl,
					       struct intel_community *community)
{
	struct intel_padgroup *gpps;
	unsigned int npins = community->npins;
	unsigned int padown_num = 0;
	size_t ngpps, i;

	if (community->gpps)
		ngpps = community->ngpps;
	else
		ngpps = DIV_ROUND_UP(community->npins, community->gpp_size);
	size_t i, ngpps = community->ngpps;

	gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL);
	if (!gpps)
		return -ENOMEM;

	for (i = 0; i < ngpps; i++) {
		if (community->gpps) {
		gpps[i] = community->gpps[i];
		} else {
			unsigned int gpp_size = community->gpp_size;

			gpps[i].reg_num = i;
			gpps[i].base = community->pin_base + i * gpp_size;
			gpps[i].size = min(gpp_size, npins);
			npins -= gpps[i].size;
		}

		if (gpps[i].size > 32)
			return -EINVAL;
@@ -1366,6 +1361,38 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
				break;
		}

		gpps[i].padown_num = padown_num;
		padown_num += DIV_ROUND_UP(gpps[i].size * 4, 32);
	}

	community->gpps = gpps;

	return 0;
}

static int intel_pinctrl_add_padgroups_by_size(struct intel_pinctrl *pctrl,
					       struct intel_community *community)
{
	struct intel_padgroup *gpps;
	unsigned int npins = community->npins;
	unsigned int padown_num = 0;
	size_t i, ngpps = DIV_ROUND_UP(npins, community->gpp_size);

	if (community->gpp_size > 32)
		return -EINVAL;

	gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL);
	if (!gpps)
		return -ENOMEM;

	for (i = 0; i < ngpps; i++) {
		unsigned int gpp_size = community->gpp_size;

		gpps[i].reg_num = i;
		gpps[i].base = community->pin_base + i * gpp_size;
		gpps[i].size = min(gpp_size, npins);
		npins -= gpps[i].size;

		gpps[i].padown_num = padown_num;

		/*
@@ -1455,7 +1482,8 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
	for (i = 0; i < pctrl->ncommunities; i++) {
		struct intel_community *community = &pctrl->communities[i];
		void __iomem *regs;
		u32 padbar;
		u32 offset;
		u32 value;

		*community = pctrl->soc->communities[i];

@@ -1463,27 +1491,48 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
		if (IS_ERR(regs))
			return PTR_ERR(regs);

		/*
		 * Determine community features based on the revision if
		 * not specified already.
		 */
		if (!community->features) {
			u32 rev;

			rev = (readl(regs + REVID) & REVID_MASK) >> REVID_SHIFT;
			if (rev >= 0x94) {
		/* Determine community features based on the revision */
		value = readl(regs + REVID);
		if (((value & REVID_MASK) >> REVID_SHIFT) >= 0x94) {
			community->features |= PINCTRL_FEATURE_DEBOUNCE;
			community->features |= PINCTRL_FEATURE_1K_PD;
		}

		/* Determine community features based on the capabilities */
		offset = CAPLIST;
		do {
			value = readl(regs + offset);
			switch ((value & CAPLIST_ID_MASK) >> CAPLIST_ID_SHIFT) {
			case CAPLIST_ID_GPIO_HW_INFO:
				community->features |= PINCTRL_FEATURE_GPIO_HW_INFO;
				break;
			case CAPLIST_ID_PWM:
				community->features |= PINCTRL_FEATURE_PWM;
				break;
			case CAPLIST_ID_BLINK:
				community->features |= PINCTRL_FEATURE_BLINK;
				break;
			case CAPLIST_ID_EXP:
				community->features |= PINCTRL_FEATURE_EXP;
				break;
			default:
				break;
			}
			offset = (value & CAPLIST_NEXT_MASK) >> CAPLIST_NEXT_SHIFT;
		} while (offset);

		dev_dbg(&pdev->dev, "Community%d features: %#08x\n", i, community->features);

		/* Read offset of the pad configuration registers */
		padbar = readl(regs + PADBAR);
		offset = readl(regs + PADBAR);

		community->regs = regs;
		community->pad_regs = regs + padbar;
		community->pad_regs = regs + offset;

		ret = intel_pinctrl_add_padgroups(pctrl, community);
		if (community->gpps)
			ret = intel_pinctrl_add_padgroups_by_gpps(pctrl, community);
		else
			ret = intel_pinctrl_add_padgroups_by_size(pctrl, community);
		if (ret)
			return ret;
	}
+4 −0
Original line number Diff line number Diff line
@@ -143,6 +143,10 @@ struct intel_community {
/* Additional features supported by the hardware */
#define PINCTRL_FEATURE_DEBOUNCE	BIT(0)
#define PINCTRL_FEATURE_1K_PD		BIT(1)
#define PINCTRL_FEATURE_GPIO_HW_INFO	BIT(2)
#define PINCTRL_FEATURE_PWM		BIT(3)
#define PINCTRL_FEATURE_BLINK		BIT(4)
#define PINCTRL_FEATURE_EXP		BIT(5)

/**
 * PIN_GROUP - Declare a pin group
+1 −0
Original line number Diff line number Diff line
@@ -748,6 +748,7 @@ static const struct intel_pinctrl_soc_data tglh_soc_data = {
static const struct acpi_device_id tgl_pinctrl_acpi_match[] = {
	{ "INT34C5", (kernel_ulong_t)&tgllp_soc_data },
	{ "INT34C6", (kernel_ulong_t)&tglh_soc_data },
	{ "INTC1055", (kernel_ulong_t)&tgllp_soc_data },
	{ }
};
MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match);