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 @@ ...@@ -29,6 +29,16 @@
#define REVID_SHIFT 16 #define REVID_SHIFT 16
#define REVID_MASK GENMASK(31, 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 PADBAR 0x00c
#define PADOWN_BITS 4 #define PADOWN_BITS 4
...@@ -1321,34 +1331,19 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) ...@@ -1321,34 +1331,19 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
return 0; 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_community *community)
{ {
struct intel_padgroup *gpps; struct intel_padgroup *gpps;
unsigned int npins = community->npins;
unsigned int padown_num = 0; unsigned int padown_num = 0;
size_t ngpps, i; size_t i, ngpps = community->ngpps;
if (community->gpps)
ngpps = community->ngpps;
else
ngpps = DIV_ROUND_UP(community->npins, community->gpp_size);
gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL); gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL);
if (!gpps) if (!gpps)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < ngpps; i++) { for (i = 0; i < ngpps; i++) {
if (community->gpps) {
gpps[i] = community->gpps[i]; 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) if (gpps[i].size > 32)
return -EINVAL; return -EINVAL;
...@@ -1366,6 +1361,38 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl, ...@@ -1366,6 +1361,38 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
break; 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; gpps[i].padown_num = padown_num;
/* /*
...@@ -1455,7 +1482,8 @@ static int intel_pinctrl_probe(struct platform_device *pdev, ...@@ -1455,7 +1482,8 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
for (i = 0; i < pctrl->ncommunities; i++) { for (i = 0; i < pctrl->ncommunities; i++) {
struct intel_community *community = &pctrl->communities[i]; struct intel_community *community = &pctrl->communities[i];
void __iomem *regs; void __iomem *regs;
u32 padbar; u32 offset;
u32 value;
*community = pctrl->soc->communities[i]; *community = pctrl->soc->communities[i];
...@@ -1463,27 +1491,48 @@ static int intel_pinctrl_probe(struct platform_device *pdev, ...@@ -1463,27 +1491,48 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
if (IS_ERR(regs)) if (IS_ERR(regs))
return PTR_ERR(regs); return PTR_ERR(regs);
/* /* Determine community features based on the revision */
* Determine community features based on the revision if value = readl(regs + REVID);
* not specified already. if (((value & REVID_MASK) >> REVID_SHIFT) >= 0x94) {
*/
if (!community->features) {
u32 rev;
rev = (readl(regs + REVID) & REVID_MASK) >> REVID_SHIFT;
if (rev >= 0x94) {
community->features |= PINCTRL_FEATURE_DEBOUNCE; community->features |= PINCTRL_FEATURE_DEBOUNCE;
community->features |= PINCTRL_FEATURE_1K_PD; 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 */ /* Read offset of the pad configuration registers */
padbar = readl(regs + PADBAR); offset = readl(regs + PADBAR);
community->regs = regs; 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) if (ret)
return ret; return ret;
} }
......
...@@ -143,6 +143,10 @@ struct intel_community { ...@@ -143,6 +143,10 @@ struct intel_community {
/* Additional features supported by the hardware */ /* Additional features supported by the hardware */
#define PINCTRL_FEATURE_DEBOUNCE BIT(0) #define PINCTRL_FEATURE_DEBOUNCE BIT(0)
#define PINCTRL_FEATURE_1K_PD BIT(1) #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 * PIN_GROUP - Declare a pin group
......
...@@ -748,6 +748,7 @@ static const struct intel_pinctrl_soc_data tglh_soc_data = { ...@@ -748,6 +748,7 @@ static const struct intel_pinctrl_soc_data tglh_soc_data = {
static const struct acpi_device_id tgl_pinctrl_acpi_match[] = { static const struct acpi_device_id tgl_pinctrl_acpi_match[] = {
{ "INT34C5", (kernel_ulong_t)&tgllp_soc_data }, { "INT34C5", (kernel_ulong_t)&tgllp_soc_data },
{ "INT34C6", (kernel_ulong_t)&tglh_soc_data }, { "INT34C6", (kernel_ulong_t)&tglh_soc_data },
{ "INTC1055", (kernel_ulong_t)&tgllp_soc_data },
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match); 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