mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
intel-pinctrl for v5.4
A collection of improvements and fixes for Intel pinctrl drivers including: - Converting drivers to use new devm_platform_ioremap_resource() helper function. - Make Interrupt Status (IS) register configurable. - Allow locked pins to be requested and used as long as they are not modified. - Fix intel_pinctrl_should_save() to translate pin number to GPIO number where needed. This fixes Asus X571GT touchpad unresponsiveness issue after suspend/resume cycle. -----BEGIN PGP SIGNATURE----- iQJUBAABCgA+FiEEVTdhRGBbNzLrSUBaAP2fSd+ZWKAFAl1uZMQgHG1pa2Eud2Vz dGVyYmVyZ0BsaW51eC5pbnRlbC5jb20ACgkQAP2fSd+ZWKA2pw/8DlFkkkdwD7te kZ/w7sEen4CCC9ch2lj7L6sBRzWT4paTebFSQxrAFuerurEm7HmTDTGKcpH1qdbR PnE6sFlVTFGHHsUcDRNQZAeWH7wE+hVnjg0wGLUllN1xc+tSI6RhUmAXpX03WBVw zVFIpoiWe9oIULMbEzri/HBNjrK25jd4v/2d703/n9/rXUULS5lEITAie/IjW8QI XSdvji41+r82YMntgdiSilb3tWW2Yak5vN1K0uC/fSJ9u9gmcPyBnX2ZwkGAjcXQ n825T0SLD+qe6aQWS6PSX+iLpur4SeGby3keOTs5E0iEcQMGUXQD/AoIC8tN/Wkn A4BIUvIBUzj0JPrRVxbbkquJimQiporzfcmuIVbRqBWAzfLXYW1jhJ8leRV8LfXF vd8ed0ff1AUcC5qR6VuvjFv3O5BJHO0ZcZ/hJC2xLXJNhCA276XCC80Ie50/EAkD HAYxDtsIoN5vVHcE9lSb1P+jSXJJsRW1vOrp9hfC9RMp8TVvE09dlVDvlHwMyf61 x7u76bPToc2kjsnr2ZP3ApZo3h2oib+pcGvSQZNMurlxAI7Qzg4Hr0hbiDYKzfC4 BvpEL9LG+qsoFm0XZeUpLLcYrExm4UgdS+XRxg5zaElBNWxy/qTDLFrZNqF+p9qv RgUMpm6HBqN5MY/GD3+lT2DcboqVGiM= =owt6 -----END PGP SIGNATURE----- Merge tag 'intel-pinctrl-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel into devel intel-pinctrl for v5.4 A collection of improvements and fixes for Intel pinctrl drivers including: - Converting drivers to use new devm_platform_ioremap_resource() helper function. - Make Interrupt Status (IS) register configurable. - Allow locked pins to be requested and used as long as they are not modified. - Fix intel_pinctrl_should_save() to translate pin number to GPIO number where needed. This fixes Asus X571GT touchpad unresponsiveness issue after suspend/resume cycle.
This commit is contained in:
commit
bacada1c3f
@ -98,13 +98,6 @@ struct byt_gpio_pin_context {
|
||||
u32 val;
|
||||
};
|
||||
|
||||
struct byt_community {
|
||||
unsigned int pin_base;
|
||||
size_t npins;
|
||||
const unsigned int *pad_map;
|
||||
void __iomem *reg_base;
|
||||
};
|
||||
|
||||
#define COMMUNITY(p, n, map) \
|
||||
{ \
|
||||
.pin_base = (p), \
|
||||
@ -112,26 +105,14 @@ struct byt_community {
|
||||
.pad_map = (map),\
|
||||
}
|
||||
|
||||
struct byt_pinctrl_soc_data {
|
||||
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 byt_community *communities;
|
||||
size_t ncommunities;
|
||||
};
|
||||
|
||||
struct byt_gpio {
|
||||
struct gpio_chip chip;
|
||||
struct platform_device *pdev;
|
||||
struct pinctrl_dev *pctl_dev;
|
||||
struct pinctrl_desc pctl_desc;
|
||||
raw_spinlock_t lock;
|
||||
const struct byt_pinctrl_soc_data *soc_data;
|
||||
struct byt_community *communities_copy;
|
||||
const struct intel_pinctrl_soc_data *soc_data;
|
||||
struct intel_community *communities_copy;
|
||||
struct byt_gpio_pin_context *saved_context;
|
||||
};
|
||||
|
||||
@ -383,11 +364,11 @@ static const struct intel_function byt_score_functions[] = {
|
||||
FUNCTION("gpio", byt_score_gpio_groups),
|
||||
};
|
||||
|
||||
static const struct byt_community byt_score_communities[] = {
|
||||
static const struct intel_community byt_score_communities[] = {
|
||||
COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
|
||||
};
|
||||
|
||||
static const struct byt_pinctrl_soc_data byt_score_soc_data = {
|
||||
static const struct intel_pinctrl_soc_data byt_score_soc_data = {
|
||||
.uid = BYT_SCORE_ACPI_UID,
|
||||
.pins = byt_score_pins,
|
||||
.npins = ARRAY_SIZE(byt_score_pins),
|
||||
@ -496,11 +477,11 @@ static const struct intel_function byt_sus_functions[] = {
|
||||
FUNCTION("gpio", byt_sus_gpio_groups),
|
||||
};
|
||||
|
||||
static const struct byt_community byt_sus_communities[] = {
|
||||
static const struct intel_community byt_sus_communities[] = {
|
||||
COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
|
||||
};
|
||||
|
||||
static const struct byt_pinctrl_soc_data byt_sus_soc_data = {
|
||||
static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
|
||||
.uid = BYT_SUS_ACPI_UID,
|
||||
.pins = byt_sus_pins,
|
||||
.npins = ARRAY_SIZE(byt_sus_pins),
|
||||
@ -549,11 +530,11 @@ static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
|
||||
3, 6, 10, 13, 2, 5, 9, 7,
|
||||
};
|
||||
|
||||
static const struct byt_community byt_ncore_communities[] = {
|
||||
static const struct intel_community byt_ncore_communities[] = {
|
||||
COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
|
||||
};
|
||||
|
||||
static const struct byt_pinctrl_soc_data byt_ncore_soc_data = {
|
||||
static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
|
||||
.uid = BYT_NCORE_ACPI_UID,
|
||||
.pins = byt_ncore_pins,
|
||||
.npins = ARRAY_SIZE(byt_ncore_pins),
|
||||
@ -561,17 +542,17 @@ static const struct byt_pinctrl_soc_data byt_ncore_soc_data = {
|
||||
.ncommunities = ARRAY_SIZE(byt_ncore_communities),
|
||||
};
|
||||
|
||||
static const struct byt_pinctrl_soc_data *byt_soc_data[] = {
|
||||
static const struct intel_pinctrl_soc_data *byt_soc_data[] = {
|
||||
&byt_score_soc_data,
|
||||
&byt_sus_soc_data,
|
||||
&byt_ncore_soc_data,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct byt_community *byt_get_community(struct byt_gpio *vg,
|
||||
unsigned int pin)
|
||||
static struct intel_community *byt_get_community(struct byt_gpio *vg,
|
||||
unsigned int pin)
|
||||
{
|
||||
struct byt_community *comm;
|
||||
struct intel_community *comm;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vg->soc_data->ncommunities; i++) {
|
||||
@ -586,7 +567,7 @@ static struct byt_community *byt_get_community(struct byt_gpio *vg,
|
||||
static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
|
||||
int reg)
|
||||
{
|
||||
struct byt_community *comm = byt_get_community(vg, offset);
|
||||
struct intel_community *comm = byt_get_community(vg, offset);
|
||||
u32 reg_offset;
|
||||
|
||||
if (!comm)
|
||||
@ -605,7 +586,7 @@ static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
|
||||
break;
|
||||
}
|
||||
|
||||
return comm->reg_base + reg_offset + reg;
|
||||
return comm->pad_regs + reg_offset + reg;
|
||||
}
|
||||
|
||||
static int byt_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
@ -1211,7 +1192,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
||||
u32 conf0, val;
|
||||
|
||||
for (i = 0; i < vg->soc_data->npins; i++) {
|
||||
const struct byt_community *comm;
|
||||
const struct intel_community *comm;
|
||||
const char *pull_str = NULL;
|
||||
const char *pull = NULL;
|
||||
void __iomem *reg;
|
||||
@ -1566,7 +1547,7 @@ static int byt_gpio_probe(struct byt_gpio *vg)
|
||||
}
|
||||
|
||||
static int byt_set_soc_data(struct byt_gpio *vg,
|
||||
const struct byt_pinctrl_soc_data *soc_data)
|
||||
const struct intel_pinctrl_soc_data *soc_data)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1579,15 +1560,13 @@ static int byt_set_soc_data(struct byt_gpio *vg,
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < soc_data->ncommunities; i++) {
|
||||
struct byt_community *comm = vg->communities_copy + i;
|
||||
struct resource *mem_rc;
|
||||
struct intel_community *comm = vg->communities_copy + i;
|
||||
|
||||
*comm = vg->soc_data->communities[i];
|
||||
|
||||
mem_rc = platform_get_resource(vg->pdev, IORESOURCE_MEM, 0);
|
||||
comm->reg_base = devm_ioremap_resource(&vg->pdev->dev, mem_rc);
|
||||
if (IS_ERR(comm->reg_base))
|
||||
return PTR_ERR(comm->reg_base);
|
||||
comm->pad_regs = devm_platform_ioremap_resource(vg->pdev, 0);
|
||||
if (IS_ERR(comm->pad_regs))
|
||||
return PTR_ERR(comm->pad_regs);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1601,8 +1580,8 @@ static const struct acpi_device_id byt_gpio_acpi_match[] = {
|
||||
|
||||
static int byt_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct byt_pinctrl_soc_data *soc_data = NULL;
|
||||
const struct byt_pinctrl_soc_data **soc_table;
|
||||
const struct intel_pinctrl_soc_data *soc_data = NULL;
|
||||
const struct intel_pinctrl_soc_data **soc_table;
|
||||
struct acpi_device *acpi_dev;
|
||||
struct byt_gpio *vg;
|
||||
int i, ret;
|
||||
@ -1611,7 +1590,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
|
||||
if (!acpi_dev)
|
||||
return -ENODEV;
|
||||
|
||||
soc_table = (const struct byt_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
|
||||
soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
|
||||
|
||||
for (i = 0; soc_table[i]; i++) {
|
||||
if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {
|
||||
|
@ -15,8 +15,9 @@
|
||||
#include "pinctrl-intel.h"
|
||||
|
||||
#define BXT_PAD_OWN 0x020
|
||||
#define BXT_HOSTSW_OWN 0x080
|
||||
#define BXT_PADCFGLOCK 0x060
|
||||
#define BXT_HOSTSW_OWN 0x080
|
||||
#define BXT_GPI_IS 0x100
|
||||
#define BXT_GPI_IE 0x110
|
||||
|
||||
#define BXT_COMMUNITY(s, e) \
|
||||
@ -24,6 +25,7 @@
|
||||
.padown_offset = BXT_PAD_OWN, \
|
||||
.padcfglock_offset = BXT_PADCFGLOCK, \
|
||||
.hostown_offset = BXT_HOSTSW_OWN, \
|
||||
.is_offset = BXT_GPI_IS, \
|
||||
.ie_offset = BXT_GPI_IE, \
|
||||
.gpp_size = 32, \
|
||||
.pin_base = (s), \
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define CNL_PADCFGLOCK 0x080
|
||||
#define CNL_LP_HOSTSW_OWN 0x0b0
|
||||
#define CNL_H_HOSTSW_OWN 0x0c0
|
||||
#define CNL_GPI_IS 0x100
|
||||
#define CNL_GPI_IE 0x120
|
||||
|
||||
#define CNL_GPP(r, s, e, g) \
|
||||
@ -37,6 +38,7 @@
|
||||
.padown_offset = CNL_PAD_OWN, \
|
||||
.padcfglock_offset = CNL_PADCFGLOCK, \
|
||||
.hostown_offset = (o), \
|
||||
.is_offset = CNL_GPI_IS, \
|
||||
.ie_offset = CNL_GPI_IE, \
|
||||
.pin_base = (s), \
|
||||
.npins = ((e) - (s) + 1), \
|
||||
|
@ -1667,7 +1667,6 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct chv_pinctrl *pctrl;
|
||||
struct acpi_device *adev;
|
||||
struct resource *res;
|
||||
acpi_status status;
|
||||
int ret, irq, i;
|
||||
|
||||
@ -1697,16 +1696,13 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
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) {
|
||||
dev_err(&pdev->dev, "failed to get interrupt number\n");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
pctrl->pctldesc = chv_pinctrl_desc;
|
||||
pctrl->pctldesc.name = dev_name(&pdev->dev);
|
||||
|
@ -15,8 +15,9 @@
|
||||
#include "pinctrl-intel.h"
|
||||
|
||||
#define DNV_PAD_OWN 0x020
|
||||
#define DNV_HOSTSW_OWN 0x0C0
|
||||
#define DNV_PADCFGLOCK 0x090
|
||||
#define DNV_HOSTSW_OWN 0x0C0
|
||||
#define DNV_GPI_IS 0x100
|
||||
#define DNV_GPI_IE 0x120
|
||||
|
||||
#define DNV_GPP(n, s, e) \
|
||||
@ -32,6 +33,7 @@
|
||||
.padown_offset = DNV_PAD_OWN, \
|
||||
.padcfglock_offset = DNV_PADCFGLOCK, \
|
||||
.hostown_offset = DNV_HOSTSW_OWN, \
|
||||
.is_offset = DNV_GPI_IS, \
|
||||
.ie_offset = DNV_GPI_IE, \
|
||||
.pin_base = (s), \
|
||||
.npins = ((e) - (s) + 1), \
|
||||
@ -39,6 +41,7 @@
|
||||
.ngpps = ARRAY_SIZE(g), \
|
||||
}
|
||||
|
||||
/* Denverton */
|
||||
static const struct pinctrl_pin_desc dnv_pins[] = {
|
||||
/* North ALL */
|
||||
PINCTRL_PIN(0, "GBE0_SDP0"),
|
||||
@ -59,7 +62,7 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
|
||||
PINCTRL_PIN(15, "NCSI_CLK_IN"),
|
||||
PINCTRL_PIN(16, "NCSI_RXD1"),
|
||||
PINCTRL_PIN(17, "NCSI_CRS_DV"),
|
||||
PINCTRL_PIN(18, "NCSI_ARB_IN"),
|
||||
PINCTRL_PIN(18, "IDSLDO_VID_TICKLE"),
|
||||
PINCTRL_PIN(19, "NCSI_TX_EN"),
|
||||
PINCTRL_PIN(20, "NCSI_TXD0"),
|
||||
PINCTRL_PIN(21, "NCSI_TXD1"),
|
||||
@ -68,14 +71,14 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
|
||||
PINCTRL_PIN(24, "GBE0_LED1"),
|
||||
PINCTRL_PIN(25, "GBE1_LED0"),
|
||||
PINCTRL_PIN(26, "GBE1_LED1"),
|
||||
PINCTRL_PIN(27, "GPIO_0"),
|
||||
PINCTRL_PIN(27, "SPARE_0"),
|
||||
PINCTRL_PIN(28, "PCIE_CLKREQ0_N"),
|
||||
PINCTRL_PIN(29, "PCIE_CLKREQ1_N"),
|
||||
PINCTRL_PIN(30, "PCIE_CLKREQ2_N"),
|
||||
PINCTRL_PIN(31, "PCIE_CLKREQ3_N"),
|
||||
PINCTRL_PIN(32, "PCIE_CLKREQ4_N"),
|
||||
PINCTRL_PIN(33, "GPIO_1"),
|
||||
PINCTRL_PIN(34, "GPIO_2"),
|
||||
PINCTRL_PIN(33, "GBE_MDC"),
|
||||
PINCTRL_PIN(34, "GBE_MDIO"),
|
||||
PINCTRL_PIN(35, "SVID_ALERT_N"),
|
||||
PINCTRL_PIN(36, "SVID_DATA"),
|
||||
PINCTRL_PIN(37, "SVID_CLK"),
|
||||
@ -102,15 +105,15 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
|
||||
PINCTRL_PIN(57, "DFX_PORT14"),
|
||||
PINCTRL_PIN(58, "DFX_PORT15"),
|
||||
/* South GPP0 */
|
||||
PINCTRL_PIN(59, "GPIO_12"),
|
||||
PINCTRL_PIN(60, "SMB5_GBE_ALRT_N"),
|
||||
PINCTRL_PIN(59, "SPI_TPM_CS_N"),
|
||||
PINCTRL_PIN(60, "UART2_CTS"),
|
||||
PINCTRL_PIN(61, "PCIE_CLKREQ5_N"),
|
||||
PINCTRL_PIN(62, "PCIE_CLKREQ6_N"),
|
||||
PINCTRL_PIN(63, "PCIE_CLKREQ7_N"),
|
||||
PINCTRL_PIN(64, "UART0_RXD"),
|
||||
PINCTRL_PIN(65, "UART0_TXD"),
|
||||
PINCTRL_PIN(66, "SMB5_GBE_CLK"),
|
||||
PINCTRL_PIN(67, "SMB5_GBE_DATA"),
|
||||
PINCTRL_PIN(66, "CPU_RESET_N"),
|
||||
PINCTRL_PIN(67, "NMI"),
|
||||
PINCTRL_PIN(68, "ERROR2_N"),
|
||||
PINCTRL_PIN(69, "ERROR1_N"),
|
||||
PINCTRL_PIN(70, "ERROR0_N"),
|
||||
@ -129,20 +132,20 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
|
||||
PINCTRL_PIN(83, "USB_OC0_N"),
|
||||
PINCTRL_PIN(84, "FLEX_CLK_SE0"),
|
||||
PINCTRL_PIN(85, "FLEX_CLK_SE1"),
|
||||
PINCTRL_PIN(86, "GPIO_4"),
|
||||
PINCTRL_PIN(87, "GPIO_5"),
|
||||
PINCTRL_PIN(88, "GPIO_6"),
|
||||
PINCTRL_PIN(89, "GPIO_7"),
|
||||
PINCTRL_PIN(86, "SPARE_4"),
|
||||
PINCTRL_PIN(87, "SMB3_IE0_CLK"),
|
||||
PINCTRL_PIN(88, "SMB3_IE0_DATA"),
|
||||
PINCTRL_PIN(89, "SMB3_IE0_ALRT_N"),
|
||||
PINCTRL_PIN(90, "SATA0_LED_N"),
|
||||
PINCTRL_PIN(91, "SATA1_LED_N"),
|
||||
PINCTRL_PIN(92, "SATA_PDETECT0"),
|
||||
PINCTRL_PIN(93, "SATA_PDETECT1"),
|
||||
PINCTRL_PIN(94, "SATA0_SDOUT"),
|
||||
PINCTRL_PIN(95, "SATA1_SDOUT"),
|
||||
PINCTRL_PIN(94, "UART1_RTS"),
|
||||
PINCTRL_PIN(95, "UART1_CTS"),
|
||||
PINCTRL_PIN(96, "UART1_RXD"),
|
||||
PINCTRL_PIN(97, "UART1_TXD"),
|
||||
PINCTRL_PIN(98, "GPIO_8"),
|
||||
PINCTRL_PIN(99, "GPIO_9"),
|
||||
PINCTRL_PIN(98, "SPARE_8"),
|
||||
PINCTRL_PIN(99, "SPARE_9"),
|
||||
PINCTRL_PIN(100, "TCK"),
|
||||
PINCTRL_PIN(101, "TRST_N"),
|
||||
PINCTRL_PIN(102, "TMS"),
|
||||
@ -150,11 +153,11 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
|
||||
PINCTRL_PIN(104, "TDO"),
|
||||
PINCTRL_PIN(105, "CX_PRDY_N"),
|
||||
PINCTRL_PIN(106, "CX_PREQ_N"),
|
||||
PINCTRL_PIN(107, "CTBTRIGINOUT"),
|
||||
PINCTRL_PIN(108, "CTBTRIGOUT"),
|
||||
PINCTRL_PIN(109, "DFX_SPARE2"),
|
||||
PINCTRL_PIN(110, "DFX_SPARE3"),
|
||||
PINCTRL_PIN(111, "DFX_SPARE4"),
|
||||
PINCTRL_PIN(107, "TAP1_TCK"),
|
||||
PINCTRL_PIN(108, "TAP1_TRST_N"),
|
||||
PINCTRL_PIN(109, "TAP1_TMS"),
|
||||
PINCTRL_PIN(110, "TAP1_TDI"),
|
||||
PINCTRL_PIN(111, "TAP1_TDO"),
|
||||
/* South GPP1 */
|
||||
PINCTRL_PIN(112, "SUSPWRDNACK"),
|
||||
PINCTRL_PIN(113, "PMU_SUSCLK"),
|
||||
@ -183,8 +186,8 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
|
||||
PINCTRL_PIN(136, "ESPI_CLK"),
|
||||
PINCTRL_PIN(137, "ESPI_RST_N"),
|
||||
PINCTRL_PIN(138, "ESPI_ALRT0_N"),
|
||||
PINCTRL_PIN(139, "GPIO_10"),
|
||||
PINCTRL_PIN(140, "GPIO_11"),
|
||||
PINCTRL_PIN(139, "ESPI_CS1_N"),
|
||||
PINCTRL_PIN(140, "ESPI_ALRT1_N"),
|
||||
PINCTRL_PIN(141, "ESPI_CLK_LOOPBK"),
|
||||
PINCTRL_PIN(142, "EMMC_CMD"),
|
||||
PINCTRL_PIN(143, "EMMC_STROBE"),
|
||||
@ -197,7 +200,7 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
|
||||
PINCTRL_PIN(150, "EMMC_D5"),
|
||||
PINCTRL_PIN(151, "EMMC_D6"),
|
||||
PINCTRL_PIN(152, "EMMC_D7"),
|
||||
PINCTRL_PIN(153, "GPIO_3"),
|
||||
PINCTRL_PIN(153, "SPARE_3"),
|
||||
};
|
||||
|
||||
static const unsigned int dnv_uart0_pins[] = { 60, 61, 64, 65 };
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define GLK_PAD_OWN 0x020
|
||||
#define GLK_PADCFGLOCK 0x080
|
||||
#define GLK_HOSTSW_OWN 0x0b0
|
||||
#define GLK_GPI_IS 0x100
|
||||
#define GLK_GPI_IE 0x110
|
||||
|
||||
#define GLK_COMMUNITY(s, e) \
|
||||
@ -24,6 +25,7 @@
|
||||
.padown_offset = GLK_PAD_OWN, \
|
||||
.padcfglock_offset = GLK_PADCFGLOCK, \
|
||||
.hostown_offset = GLK_HOSTSW_OWN, \
|
||||
.is_offset = GLK_GPI_IS, \
|
||||
.ie_offset = GLK_GPI_IE, \
|
||||
.gpp_size = 32, \
|
||||
.pin_base = (s), \
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define ICL_PAD_OWN 0x020
|
||||
#define ICL_PADCFGLOCK 0x080
|
||||
#define ICL_HOSTSW_OWN 0x0b0
|
||||
#define ICL_GPI_IS 0x100
|
||||
#define ICL_GPI_IE 0x110
|
||||
|
||||
#define ICL_GPP(r, s, e, g) \
|
||||
@ -36,6 +37,7 @@
|
||||
.padown_offset = ICL_PAD_OWN, \
|
||||
.padcfglock_offset = ICL_PADCFGLOCK, \
|
||||
.hostown_offset = ICL_HOSTSW_OWN, \
|
||||
.is_offset = ICL_GPI_IS, \
|
||||
.ie_offset = ICL_GPI_IE, \
|
||||
.pin_base = (s), \
|
||||
.npins = ((e) - (s) + 1), \
|
||||
|
@ -8,12 +8,13 @@
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
@ -29,7 +30,6 @@
|
||||
#define REVID_MASK GENMASK(31, 16)
|
||||
|
||||
#define PADBAR 0x00c
|
||||
#define GPI_IS 0x100
|
||||
|
||||
#define PADOWN_BITS 4
|
||||
#define PADOWN_SHIFT(p) ((p) % 8 * PADOWN_BITS)
|
||||
@ -71,7 +71,7 @@
|
||||
#define PADCFG2_DEBOUNCE_SHIFT 1
|
||||
#define PADCFG2_DEBOUNCE_MASK GENMASK(4, 1)
|
||||
|
||||
#define DEBOUNCE_PERIOD 31250 /* ns */
|
||||
#define DEBOUNCE_PERIOD_NSEC 31250
|
||||
|
||||
struct intel_pad_context {
|
||||
u32 padcfg0;
|
||||
@ -165,7 +165,7 @@ static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl,
|
||||
padno = pin_to_padno(community, pin);
|
||||
nregs = (community->features & PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2;
|
||||
|
||||
if (reg == PADCFG2 && !(community->features & PINCTRL_FEATURE_DEBOUNCE))
|
||||
if (reg >= nregs * 4)
|
||||
return NULL;
|
||||
|
||||
return community->pad_regs + reg + padno * nregs * 4;
|
||||
@ -220,47 +220,71 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin)
|
||||
return !(readl(hostown) & BIT(gpp_offset));
|
||||
}
|
||||
|
||||
static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
|
||||
/**
|
||||
* enum - Locking variants of the pad configuration
|
||||
*
|
||||
* @PAD_UNLOCKED: pad is fully controlled by the configuration registers
|
||||
* @PAD_LOCKED: pad configuration registers, except TX state, are locked
|
||||
* @PAD_LOCKED_TX: pad configuration TX state is locked
|
||||
* @PAD_LOCKED_FULL: pad configuration registers are locked completely
|
||||
*
|
||||
* Locking is considered as read-only mode for corresponding registers and
|
||||
* their respective fields. That said, TX state bit is locked separately from
|
||||
* the main locking scheme.
|
||||
*/
|
||||
enum {
|
||||
PAD_UNLOCKED = 0,
|
||||
PAD_LOCKED = 1,
|
||||
PAD_LOCKED_TX = 2,
|
||||
PAD_LOCKED_FULL = PAD_LOCKED | PAD_LOCKED_TX,
|
||||
};
|
||||
|
||||
static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
|
||||
{
|
||||
struct intel_community *community;
|
||||
const struct intel_padgroup *padgrp;
|
||||
unsigned int offset, gpp_offset;
|
||||
u32 value;
|
||||
int ret = PAD_UNLOCKED;
|
||||
|
||||
community = intel_get_community(pctrl, pin);
|
||||
if (!community)
|
||||
return true;
|
||||
return PAD_LOCKED_FULL;
|
||||
if (!community->padcfglock_offset)
|
||||
return false;
|
||||
return PAD_UNLOCKED;
|
||||
|
||||
padgrp = intel_community_get_padgroup(community, pin);
|
||||
if (!padgrp)
|
||||
return true;
|
||||
return PAD_LOCKED_FULL;
|
||||
|
||||
gpp_offset = padgroup_offset(padgrp, pin);
|
||||
|
||||
/*
|
||||
* If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
|
||||
* the pad is considered unlocked. Any other case means that it is
|
||||
* either fully or partially locked and we don't touch it.
|
||||
* either fully or partially locked.
|
||||
*/
|
||||
offset = community->padcfglock_offset + padgrp->reg_num * 8;
|
||||
offset = community->padcfglock_offset + 0 + padgrp->reg_num * 8;
|
||||
value = readl(community->regs + offset);
|
||||
if (value & BIT(gpp_offset))
|
||||
return true;
|
||||
ret |= PAD_LOCKED;
|
||||
|
||||
offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8;
|
||||
value = readl(community->regs + offset);
|
||||
if (value & BIT(gpp_offset))
|
||||
return true;
|
||||
ret |= PAD_LOCKED_TX;
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool intel_pad_is_unlocked(struct intel_pinctrl *pctrl, unsigned int pin)
|
||||
{
|
||||
return (intel_pad_locked(pctrl, pin) & PAD_LOCKED) == PAD_UNLOCKED;
|
||||
}
|
||||
|
||||
static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin)
|
||||
{
|
||||
return intel_pad_owned_by_host(pctrl, pin) &&
|
||||
!intel_pad_locked(pctrl, pin);
|
||||
return intel_pad_owned_by_host(pctrl, pin) && intel_pad_is_unlocked(pctrl, pin);
|
||||
}
|
||||
|
||||
static int intel_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
@ -294,7 +318,8 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
|
||||
void __iomem *padcfg;
|
||||
u32 cfg0, cfg1, mode;
|
||||
bool locked, acpi;
|
||||
int locked;
|
||||
bool acpi;
|
||||
|
||||
if (!intel_pad_owned_by_host(pctrl, pin)) {
|
||||
seq_puts(s, "not available");
|
||||
@ -322,11 +347,16 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||
|
||||
if (locked || acpi) {
|
||||
seq_puts(s, " [");
|
||||
if (locked) {
|
||||
if (locked)
|
||||
seq_puts(s, "LOCKED");
|
||||
if (acpi)
|
||||
seq_puts(s, ", ");
|
||||
}
|
||||
if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_TX)
|
||||
seq_puts(s, " tx");
|
||||
else if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_FULL)
|
||||
seq_puts(s, " full");
|
||||
|
||||
if (locked && acpi)
|
||||
seq_puts(s, ", ");
|
||||
|
||||
if (acpi)
|
||||
seq_puts(s, "ACPI");
|
||||
seq_puts(s, "]");
|
||||
@ -448,11 +478,16 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
|
||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||
|
||||
if (!intel_pad_usable(pctrl, pin)) {
|
||||
if (!intel_pad_owned_by_host(pctrl, pin)) {
|
||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (!intel_pad_is_unlocked(pctrl, pin)) {
|
||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
|
||||
intel_gpio_set_gpio_mode(padcfg0);
|
||||
/* Disable TX buffer and enable RX (this will be input) */
|
||||
@ -566,7 +601,7 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
return -EINVAL;
|
||||
|
||||
v = (v & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT;
|
||||
arg = BIT(v) * DEBOUNCE_PERIOD / 1000;
|
||||
arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -683,7 +718,7 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
|
||||
if (debounce) {
|
||||
unsigned long v;
|
||||
|
||||
v = order_base_2(debounce * 1000 / DEBOUNCE_PERIOD);
|
||||
v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC);
|
||||
if (v < 3 || v > 15) {
|
||||
ret = -EINVAL;
|
||||
goto exit_unlock;
|
||||
@ -796,6 +831,29 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_pin_to_gpio() - Translate from pin number to GPIO offset
|
||||
* @pctrl: Pinctrl structure
|
||||
* @pin: pin number
|
||||
*
|
||||
* Translate the pin number of pinctrl to GPIO offset
|
||||
*/
|
||||
static int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin)
|
||||
{
|
||||
const struct intel_community *community;
|
||||
const struct intel_padgroup *padgrp;
|
||||
|
||||
community = intel_get_community(pctrl, pin);
|
||||
if (!community)
|
||||
return -EINVAL;
|
||||
|
||||
padgrp = intel_community_get_padgroup(community, pin);
|
||||
if (!padgrp)
|
||||
return -EINVAL;
|
||||
|
||||
return pin - padgrp->base + padgrp->gpio_base;
|
||||
}
|
||||
|
||||
static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
|
||||
@ -1313,15 +1371,12 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
|
||||
|
||||
for (i = 0; i < pctrl->ncommunities; i++) {
|
||||
struct intel_community *community = &pctrl->communities[i];
|
||||
struct resource *res;
|
||||
void __iomem *regs;
|
||||
u32 padbar;
|
||||
|
||||
*community = pctrl->soc->communities[i];
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM,
|
||||
community->barno);
|
||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
regs = devm_platform_ioremap_resource(pdev, community->barno);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
@ -1345,19 +1400,14 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
|
||||
community->regs = regs;
|
||||
community->pad_regs = regs + padbar;
|
||||
|
||||
if (!community->is_offset)
|
||||
community->is_offset = GPI_IS;
|
||||
|
||||
ret = intel_pinctrl_add_padgroups(pctrl, community);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "failed to get interrupt number\n");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
ret = intel_pinctrl_pm_init(pctrl);
|
||||
if (ret)
|
||||
@ -1421,8 +1471,6 @@ int intel_pinctrl_probe_by_uid(struct platform_device *pdev)
|
||||
table = (const struct intel_pinctrl_soc_data **)id->driver_data;
|
||||
data = table[pdev->id];
|
||||
}
|
||||
if (!data)
|
||||
return -ENODEV;
|
||||
|
||||
return intel_pinctrl_probe(pdev, data);
|
||||
}
|
||||
@ -1443,7 +1491,7 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int
|
||||
* them alone.
|
||||
*/
|
||||
if (pd->mux_owner || pd->gpio_owner ||
|
||||
gpiochip_line_is_irq(&pctrl->chip, pin))
|
||||
gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -75,9 +75,9 @@ struct intel_padgroup {
|
||||
* @hostown_offset: Register offset of HOSTSW_OWN from @regs. If %0 then it
|
||||
* is assumed that the host owns the pin (rather than
|
||||
* ACPI).
|
||||
* @is_offset: Register offset of GPI_IS from @regs. If %0 then uses the
|
||||
* default (%0x100).
|
||||
* @is_offset: Register offset of GPI_IS from @regs.
|
||||
* @ie_offset: Register offset of GPI_IE from @regs.
|
||||
* @features: Additional features supported by the hardware
|
||||
* @pin_base: Starting pin of pins in this community
|
||||
* @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK,
|
||||
* HOSTSW_OWN, GPI_IS, GPI_IE, etc. Used when @gpps is %NULL.
|
||||
@ -85,9 +85,9 @@ struct intel_padgroup {
|
||||
* minimum. Use %0 if the number of registers can be
|
||||
* determined by the size of the group.
|
||||
* @npins: Number of pins in this community
|
||||
* @features: Additional features supported by the hardware
|
||||
* @gpps: Pad groups if the controller has variable size pad groups
|
||||
* @ngpps: Number of pad groups in this community
|
||||
* @pad_map: Optional non-linear mapping of the pads
|
||||
* @regs: Community specific common registers (reserved for core driver)
|
||||
* @pad_regs: Community specific pad registers (reserved for core driver)
|
||||
*
|
||||
@ -104,13 +104,14 @@ struct intel_community {
|
||||
unsigned int hostown_offset;
|
||||
unsigned int is_offset;
|
||||
unsigned int ie_offset;
|
||||
unsigned int features;
|
||||
unsigned int pin_base;
|
||||
unsigned int gpp_size;
|
||||
unsigned int gpp_num_padown_regs;
|
||||
size_t npins;
|
||||
unsigned int features;
|
||||
const struct intel_padgroup *gpps;
|
||||
size_t ngpps;
|
||||
const unsigned int *pad_map;
|
||||
/* Reserved for the core driver */
|
||||
void __iomem *regs;
|
||||
void __iomem *pad_regs;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define LBG_PAD_OWN 0x020
|
||||
#define LBG_PADCFGLOCK 0x060
|
||||
#define LBG_HOSTSW_OWN 0x080
|
||||
#define LBG_GPI_IS 0x100
|
||||
#define LBG_GPI_IE 0x110
|
||||
|
||||
#define LBG_COMMUNITY(b, s, e) \
|
||||
@ -25,6 +26,7 @@
|
||||
.padown_offset = LBG_PAD_OWN, \
|
||||
.padcfglock_offset = LBG_PADCFGLOCK, \
|
||||
.hostown_offset = LBG_HOSTSW_OWN, \
|
||||
.is_offset = LBG_GPI_IS, \
|
||||
.ie_offset = LBG_GPI_IE, \
|
||||
.gpp_size = 24, \
|
||||
.pin_base = (s), \
|
||||
|
@ -885,7 +885,6 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mrfld_family *families;
|
||||
struct mrfld_pinctrl *mp;
|
||||
struct resource *mem;
|
||||
void __iomem *regs;
|
||||
size_t nfamilies;
|
||||
unsigned int i;
|
||||
@ -897,8 +896,7 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev)
|
||||
mp->dev = &pdev->dev;
|
||||
raw_spin_lock_init(&mp->lock);
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(&pdev->dev, mem);
|
||||
regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define SPT_PAD_OWN 0x020
|
||||
#define SPT_PADCFGLOCK 0x0a0
|
||||
#define SPT_HOSTSW_OWN 0x0d0
|
||||
#define SPT_GPI_IS 0x100
|
||||
#define SPT_GPI_IE 0x120
|
||||
|
||||
#define SPT_COMMUNITY(b, s, e) \
|
||||
@ -26,6 +27,7 @@
|
||||
.padown_offset = SPT_PAD_OWN, \
|
||||
.padcfglock_offset = SPT_PADCFGLOCK, \
|
||||
.hostown_offset = SPT_HOSTSW_OWN, \
|
||||
.is_offset = SPT_GPI_IS, \
|
||||
.ie_offset = SPT_GPI_IE, \
|
||||
.gpp_size = 24, \
|
||||
.gpp_num_padown_regs = 4, \
|
||||
|
Loading…
Reference in New Issue
Block a user