Commit 40075341 authored by Linus Walleij's avatar Linus Walleij

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
......@@ -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,
struct intel_community *community)
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;
}
gpps[i] = community->gpps[i];
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;
/* 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;
}
rev = (readl(regs + REVID) & REVID_MASK) >> REVID_SHIFT;
if (rev >= 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;
}
......
......@@ -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
......
......@@ -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);
......
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