diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2020-09-22 00:44:41 +0300 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2020-09-22 00:44:41 +0300 |
commit | 5b398f8fc186d48bb6a0966aa5c6ce12535f8e33 (patch) | |
tree | 000cea7f87bb07dcfd108a76c78b85ecca37eb59 /drivers/pinctrl | |
parent | e777f8c8f9f6a3fe4f42f5f101620adc60b78616 (diff) | |
parent | a0bf06dc51dbbc5ad182b1bcf4d879db8d297c5e (diff) | |
download | linux-5b398f8fc186d48bb6a0966aa5c6ce12535f8e33.tar.xz |
Merge tag 'intel-pinctrl-v5.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel into devel
intel-pinctrl for v5.10-1
* Add last part of cleanup Cherryview driver to align with other drivers
* Due to above clean up Cherryview and Baytrail drivers to use common API
The following is an automated git shortlog grouped by driver:
baytrail:
- Switch to use intel_pinctrl_get_soc_data()
cherryview:
- Preserve CHV_PADCTRL1_INVRXTX_TXDATA flag on GPIOs
- Switch to use intel_pinctrl_get_soc_data()
- Utilize temporary variable to hold device pointer
- Switch to use struct intel_pinctrl
- Move custom community members to separate data struct
- Drop stale comment
intel:
- Update header block to reflect direct dependencies
- Extract intel_pinctrl_get_soc_data() helper for wider use
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/intel/Kconfig | 12 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-baytrail.c | 24 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-cherryview.c | 184 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.c | 24 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.h | 7 |
5 files changed, 117 insertions, 134 deletions
diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index b3e6060db52d..28e5f824ba45 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -6,11 +6,7 @@ if (X86 || COMPILE_TEST) config PINCTRL_BAYTRAIL bool "Intel Baytrail GPIO pin control" depends on ACPI - select GPIOLIB - select GPIOLIB_IRQCHIP - select PINMUX - select PINCONF - select GENERIC_PINCONF + select PINCTRL_INTEL help driver for memory mapped GPIO functionality on Intel Baytrail platforms. Supports 3 banks with 102, 28 and 44 gpios. @@ -22,11 +18,7 @@ config PINCTRL_BAYTRAIL config PINCTRL_CHERRYVIEW tristate "Intel Cherryview/Braswell pinctrl and GPIO driver" depends on ACPI - select PINMUX - select PINCONF - select GENERIC_PINCONF - select GPIOLIB - select GPIOLIB_IRQCHIP + select PINCTRL_INTEL help Cherryview/Braswell pinctrl driver provides an interface that allows configuring of SoC pins and using them as GPIOs. diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index d6e35cba3065..d49aab3cfbaa 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1635,28 +1635,14 @@ static const struct acpi_device_id byt_gpio_acpi_match[] = { static int byt_pinctrl_probe(struct platform_device *pdev) { - const struct intel_pinctrl_soc_data *soc_data = NULL; - const struct intel_pinctrl_soc_data **soc_table; + const struct intel_pinctrl_soc_data *soc_data; struct device *dev = &pdev->dev; - struct acpi_device *acpi_dev; struct intel_pinctrl *vg; - int i, ret; - - acpi_dev = ACPI_COMPANION(dev); - if (!acpi_dev) - return -ENODEV; - - soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(dev); - - for (i = 0; soc_table[i]; i++) { - if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) { - soc_data = soc_table[i]; - break; - } - } + int ret; - if (!soc_data) - return -ENODEV; + soc_data = intel_pinctrl_get_soc_data(pdev); + if (IS_ERR(soc_data)) + return PTR_ERR(soc_data); vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL); if (!vg) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 9ef246145bde..2ed17cdf946d 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -58,6 +58,7 @@ #define CHV_PADCTRL1_CFGLOCK BIT(31) #define CHV_PADCTRL1_INVRXTX_SHIFT 4 #define CHV_PADCTRL1_INVRXTX_MASK GENMASK(7, 4) +#define CHV_PADCTRL1_INVRXTX_TXDATA BIT(7) #define CHV_PADCTRL1_INVRXTX_RXDATA BIT(6) #define CHV_PADCTRL1_INVRXTX_TXENABLE BIT(5) #define CHV_PADCTRL1_ODEN BIT(3) @@ -73,35 +74,11 @@ struct intel_pad_context { }; /** - * struct chv_pinctrl - CHV pinctrl private structure - * @dev: Pointer to the parent device - * @pctldesc: Pin controller description - * @pctldev: Pointer to the pin controller device - * @chip: GPIO chip in this pin controller - * @irqchip: IRQ chip in this pin controller - * @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 + * struct intel_community_context - community context for Cherryview * @intr_lines: Mapping between 16 HW interrupt wires and GPIO offset (in GPIO number space) * @saved_intmask: Interrupt mask saved for system sleep - * - * The first group in @groups is expected to contain all pins that can be - * used as GPIOs. */ -struct chv_pinctrl { - struct device *dev; - struct pinctrl_desc pctldesc; - struct pinctrl_dev *pctldev; - struct gpio_chip chip; - struct irq_chip irqchip; - const struct intel_pinctrl_soc_data *soc; - struct intel_community *communities; - size_t ncommunities; - struct intel_pinctrl_context context; - int irq; - +struct intel_community_context { unsigned int intr_lines[16]; u32 saved_intmask; }; @@ -587,14 +564,14 @@ static const struct intel_pinctrl_soc_data *chv_soc_data[] = { */ static DEFINE_RAW_SPINLOCK(chv_lock); -static u32 chv_pctrl_readl(struct chv_pinctrl *pctrl, unsigned int offset) +static u32 chv_pctrl_readl(struct intel_pinctrl *pctrl, unsigned int 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) +static void chv_pctrl_writel(struct intel_pinctrl *pctrl, unsigned int offset, u32 value) { const struct intel_community *community = &pctrl->communities[0]; void __iomem *reg = community->regs + offset; @@ -604,7 +581,7 @@ static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 readl(reg); } -static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset, +static void __iomem *chv_padreg(struct intel_pinctrl *pctrl, unsigned int offset, unsigned int reg) { const struct intel_community *community = &pctrl->communities[0]; @@ -616,12 +593,12 @@ static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset, return community->pad_regs + offset + reg; } -static u32 chv_readl(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset) +static u32 chv_readl(struct intel_pinctrl *pctrl, unsigned int pin, unsigned int offset) { return readl(chv_padreg(pctrl, pin, offset)); } -static void chv_writel(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset, u32 value) +static void chv_writel(struct intel_pinctrl *pctrl, unsigned int pin, unsigned int offset, u32 value) { void __iomem *reg = chv_padreg(pctrl, pin, offset); @@ -631,14 +608,14 @@ static void chv_writel(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int } /* When Pad Cfg is locked, driver can only change GPIOTXState or GPIORXState */ -static bool chv_pad_locked(struct chv_pinctrl *pctrl, unsigned int offset) +static bool chv_pad_locked(struct intel_pinctrl *pctrl, unsigned int offset) { return chv_readl(pctrl, offset, CHV_PADCTRL1) & CHV_PADCTRL1_CFGLOCK; } static int chv_get_groups_count(struct pinctrl_dev *pctldev) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); return pctrl->soc->ngroups; } @@ -646,7 +623,7 @@ static int chv_get_groups_count(struct pinctrl_dev *pctldev) static const char *chv_get_group_name(struct pinctrl_dev *pctldev, unsigned int group) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); return pctrl->soc->groups[group].name; } @@ -654,7 +631,7 @@ static const char *chv_get_group_name(struct pinctrl_dev *pctldev, static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, const unsigned int **pins, unsigned int *npins) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); *pins = pctrl->soc->groups[group].pins; *npins = pctrl->soc->groups[group].npins; @@ -664,7 +641,7 @@ static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned int offset) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); unsigned long flags; u32 ctrl0, ctrl1; bool locked; @@ -703,7 +680,7 @@ static const struct pinctrl_ops chv_pinctrl_ops = { static int chv_get_functions_count(struct pinctrl_dev *pctldev) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); return pctrl->soc->nfunctions; } @@ -711,7 +688,7 @@ static int chv_get_functions_count(struct pinctrl_dev *pctldev) static const char *chv_get_function_name(struct pinctrl_dev *pctldev, unsigned int function) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); return pctrl->soc->functions[function].name; } @@ -721,7 +698,7 @@ static int chv_get_function_groups(struct pinctrl_dev *pctldev, const char * const **groups, unsigned int * const ngroups) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); *groups = pctrl->soc->functions[function].groups; *ngroups = pctrl->soc->functions[function].ngroups; @@ -731,7 +708,7 @@ static int chv_get_function_groups(struct pinctrl_dev *pctldev, static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, unsigned int group) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); const struct intel_pingroup *grp; unsigned long flags; int i; @@ -789,14 +766,25 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, return 0; } -static void chv_gpio_clear_triggering(struct chv_pinctrl *pctrl, +static void chv_gpio_clear_triggering(struct intel_pinctrl *pctrl, unsigned int offset) { + u32 invrxtx_mask = CHV_PADCTRL1_INVRXTX_MASK; u32 value; + /* + * One some devices the GPIO should output the inverted value from what + * device-drivers / ACPI code expects (inverted external buffer?). The + * BIOS makes this work by setting the CHV_PADCTRL1_INVRXTX_TXDATA flag, + * preserve this flag if the pin is already setup as GPIO. + */ + value = chv_readl(pctrl, offset, CHV_PADCTRL0); + if (value & CHV_PADCTRL0_GPIOEN) + invrxtx_mask &= ~CHV_PADCTRL1_INVRXTX_TXDATA; + value = chv_readl(pctrl, offset, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; - value &= ~CHV_PADCTRL1_INVRXTX_MASK; + value &= ~invrxtx_mask; chv_writel(pctrl, offset, CHV_PADCTRL1, value); } @@ -804,7 +792,7 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int offset) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); unsigned long flags; u32 value; @@ -818,12 +806,13 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, return -EBUSY; } } else { + struct intel_community_context *cctx = &pctrl->context.communities[0]; int i; /* Reset the interrupt mapping */ - for (i = 0; i < ARRAY_SIZE(pctrl->intr_lines); i++) { - if (pctrl->intr_lines[i] == offset) { - pctrl->intr_lines[i] = 0; + for (i = 0; i < ARRAY_SIZE(cctx->intr_lines); i++) { + if (cctx->intr_lines[i] == offset) { + cctx->intr_lines[i] = 0; break; } } @@ -857,7 +846,7 @@ static void chv_gpio_disable_free(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int offset) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); unsigned long flags; raw_spin_lock_irqsave(&chv_lock, flags); @@ -872,7 +861,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int offset, bool input) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); unsigned long flags; u32 ctrl0; @@ -903,7 +892,7 @@ static const struct pinmux_ops chv_pinmux_ops = { static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); enum pin_config_param param = pinconf_to_config_param(*config); unsigned long flags; u32 ctrl0, ctrl1; @@ -980,7 +969,7 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, return 0; } -static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, +static int chv_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, enum pin_config_param param, u32 arg) { unsigned long flags; @@ -1045,7 +1034,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, return 0; } -static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin, +static int chv_config_set_oden(struct intel_pinctrl *pctrl, unsigned int pin, bool enable) { unsigned long flags; @@ -1068,7 +1057,7 @@ static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin, static int chv_config_set(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *configs, unsigned int nconfigs) { - struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); enum pin_config_param param; int i, ret; u32 arg; @@ -1169,7 +1158,7 @@ static struct pinctrl_desc chv_pinctrl_desc = { static int chv_gpio_get(struct gpio_chip *chip, unsigned int offset) { - struct chv_pinctrl *pctrl = gpiochip_get_data(chip); + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); unsigned long flags; u32 ctrl0, cfg; @@ -1187,7 +1176,7 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned int offset) static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { - struct chv_pinctrl *pctrl = gpiochip_get_data(chip); + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); unsigned long flags; u32 ctrl0; @@ -1207,7 +1196,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { - struct chv_pinctrl *pctrl = gpiochip_get_data(chip); + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); u32 ctrl0, direction; unsigned long flags; @@ -1250,7 +1239,7 @@ static const struct gpio_chip chv_gpio_chip = { static void chv_gpio_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct chv_pinctrl *pctrl = gpiochip_get_data(gc); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); int pin = irqd_to_hwirq(d); u32 intr_line; @@ -1267,7 +1256,7 @@ static void chv_gpio_irq_ack(struct irq_data *d) static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct chv_pinctrl *pctrl = gpiochip_get_data(gc); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); int pin = irqd_to_hwirq(d); u32 value, intr_line; unsigned long flags; @@ -1312,7 +1301,8 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) */ if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct chv_pinctrl *pctrl = gpiochip_get_data(gc); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + struct intel_community_context *cctx = &pctrl->context.communities[0]; unsigned int pin = irqd_to_hwirq(d); irq_flow_handler_t handler; unsigned long flags; @@ -1329,9 +1319,9 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) else handler = handle_edge_irq; - if (!pctrl->intr_lines[intsel]) { + if (!cctx->intr_lines[intsel]) { irq_set_handler_locked(d, handler); - pctrl->intr_lines[intsel] = pin; + cctx->intr_lines[intsel] = pin; } raw_spin_unlock_irqrestore(&chv_lock, flags); } @@ -1343,7 +1333,8 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct chv_pinctrl *pctrl = gpiochip_get_data(gc); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + struct intel_community_context *cctx = &pctrl->context.communities[0]; unsigned int pin = irqd_to_hwirq(d); unsigned long flags; u32 value; @@ -1388,7 +1379,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) value &= CHV_PADCTRL0_INTSEL_MASK; value >>= CHV_PADCTRL0_INTSEL_SHIFT; - pctrl->intr_lines[value] = pin; + cctx->intr_lines[value] = pin; if (type & IRQ_TYPE_EDGE_BOTH) irq_set_handler_locked(d, handle_edge_irq); @@ -1403,8 +1394,9 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) 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); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); const struct intel_community *community = &pctrl->communities[0]; + struct intel_community_context *cctx = &pctrl->context.communities[0]; struct irq_chip *chip = irq_desc_get_chip(desc); unsigned long pending; unsigned long flags; @@ -1419,7 +1411,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) for_each_set_bit(intr_line, &pending, community->nirqs) { unsigned int irq, offset; - offset = pctrl->intr_lines[intr_line]; + offset = cctx->intr_lines[intr_line]; irq = irq_find_mapping(gc->irq.domain, offset); generic_handle_irq(irq); } @@ -1472,7 +1464,7 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask, unsigned int ngpios) { - struct chv_pinctrl *pctrl = gpiochip_get_data(chip); + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); const struct intel_community *community = &pctrl->communities[0]; int i; @@ -1494,7 +1486,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); + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); const struct intel_community *community = &pctrl->communities[0]; /* @@ -1520,7 +1512,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); + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); const struct intel_community *community = &pctrl->communities[0]; const struct intel_padgroup *gpp; int ret, i; @@ -1539,7 +1531,7 @@ static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) return 0; } -static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) +static int chv_gpio_probe(struct intel_pinctrl *pctrl, int irq) { const struct intel_community *community = &pctrl->communities[0]; const struct intel_padgroup *gpp; @@ -1605,7 +1597,7 @@ static acpi_status chv_pinctrl_mmio_access_handler(u32 function, acpi_physical_address address, u32 bits, u64 *value, void *handler_context, void *region_context) { - struct chv_pinctrl *pctrl = region_context; + struct intel_pinctrl *pctrl = region_context; unsigned long flags; acpi_status ret = AE_OK; @@ -1625,34 +1617,23 @@ 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; + const struct intel_pinctrl_soc_data *soc_data; struct intel_community *community; struct device *dev = &pdev->dev; - struct chv_pinctrl *pctrl; - struct acpi_device *adev; + struct acpi_device *adev = ACPI_COMPANION(dev); + struct intel_pinctrl *pctrl; acpi_status status; - int ret, irq, i; + int ret, irq; - adev = ACPI_COMPANION(&pdev->dev); - if (!adev) - return -ENODEV; - - 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 (!soc_data) - return -ENODEV; + soc_data = intel_pinctrl_get_soc_data(pdev); + if (IS_ERR(soc_data)) + return PTR_ERR(soc_data); pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); if (!pctrl) return -ENOMEM; - pctrl->dev = &pdev->dev; + pctrl->dev = dev; pctrl->soc = soc_data; pctrl->ncommunities = pctrl->soc->ncommunities; @@ -1677,19 +1658,24 @@ static int chv_pinctrl_probe(struct platform_device *pdev) return -ENOMEM; #endif + pctrl->context.communities = devm_kcalloc(dev, pctrl->soc->ncommunities, + sizeof(*pctrl->context.communities), + GFP_KERNEL); + if (!pctrl->context.communities) + return -ENOMEM; + 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.name = dev_name(dev); pctrl->pctldesc.pins = pctrl->soc->pins; pctrl->pctldesc.npins = pctrl->soc->npins; - pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc, - pctrl); + pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl); if (IS_ERR(pctrl->pctldev)) { - dev_err(&pdev->dev, "failed to register pinctrl driver\n"); + dev_err(dev, "failed to register pinctrl driver\n"); return PTR_ERR(pctrl->pctldev); } @@ -1702,7 +1688,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev) chv_pinctrl_mmio_access_handler, NULL, pctrl); if (ACPI_FAILURE(status)) - dev_err(&pdev->dev, "failed to install ACPI addr space handler\n"); + dev_err(dev, "failed to install ACPI addr space handler\n"); platform_set_drvdata(pdev, pctrl); @@ -1711,7 +1697,7 @@ 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); + struct intel_pinctrl *pctrl = platform_get_drvdata(pdev); const struct intel_community *community = &pctrl->communities[0]; acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev), @@ -1724,13 +1710,14 @@ static int chv_pinctrl_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int chv_pinctrl_suspend_noirq(struct device *dev) { - struct chv_pinctrl *pctrl = dev_get_drvdata(dev); + struct intel_pinctrl *pctrl = dev_get_drvdata(dev); + struct intel_community_context *cctx = &pctrl->context.communities[0]; unsigned long flags; int i; raw_spin_lock_irqsave(&chv_lock, flags); - pctrl->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); + cctx->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); for (i = 0; i < pctrl->soc->npins; i++) { const struct pinctrl_pin_desc *desc; @@ -1753,7 +1740,8 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) static int chv_pinctrl_resume_noirq(struct device *dev) { - struct chv_pinctrl *pctrl = dev_get_drvdata(dev); + struct intel_pinctrl *pctrl = dev_get_drvdata(dev); + struct intel_community_context *cctx = &pctrl->context.communities[0]; unsigned long flags; int i; @@ -1797,7 +1785,7 @@ static int chv_pinctrl_resume_noirq(struct device *dev) * the interrupt mask register as well. */ chv_pctrl_writel(pctrl, CHV_INTSTAT, 0xffff); - chv_pctrl_writel(pctrl, CHV_INTMASK, pctrl->saved_intmask); + chv_pctrl_writel(pctrl, CHV_INTMASK, cctx->saved_intmask); raw_spin_unlock_irqrestore(&chv_lock, flags); diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index b64997b303e0..154ce3f908cd 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1414,9 +1414,6 @@ static int intel_pinctrl_probe(struct platform_device *pdev, struct intel_pinctrl *pctrl; int i, ret, irq; - if (!soc_data) - return -EINVAL; - pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); if (!pctrl) return -ENOMEM; @@ -1505,12 +1502,27 @@ int intel_pinctrl_probe_by_hid(struct platform_device *pdev) const struct intel_pinctrl_soc_data *data; data = device_get_match_data(&pdev->dev); + if (!data) + return -ENODATA; + return intel_pinctrl_probe(pdev, data); } EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_hid); int intel_pinctrl_probe_by_uid(struct platform_device *pdev) { + const struct intel_pinctrl_soc_data *data; + + data = intel_pinctrl_get_soc_data(pdev); + if (IS_ERR(data)) + return PTR_ERR(data); + + return intel_pinctrl_probe(pdev, data); +} +EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_uid); + +const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_device *pdev) +{ const struct intel_pinctrl_soc_data *data = NULL; const struct intel_pinctrl_soc_data **table; struct acpi_device *adev; @@ -1532,15 +1544,15 @@ int intel_pinctrl_probe_by_uid(struct platform_device *pdev) id = platform_get_device_id(pdev); if (!id) - return -ENODEV; + return ERR_PTR(-ENODEV); table = (const struct intel_pinctrl_soc_data **)id->driver_data; data = table[pdev->id]; } - return intel_pinctrl_probe(pdev, data); + return data ?: ERR_PTR(-ENODATA); } -EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_uid); +EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data); #ifdef CONFIG_PM_SLEEP static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin) diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index 4e17308d33e9..ad34b7a3f6ed 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -10,12 +10,15 @@ #ifndef PINCTRL_INTEL_H #define PINCTRL_INTEL_H +#include <linux/bits.h> +#include <linux/compiler_types.h> #include <linux/gpio/driver.h> #include <linux/irq.h> +#include <linux/kernel.h> #include <linux/pm.h> +#include <linux/pinctrl/pinctrl.h> #include <linux/spinlock_types.h> -struct pinctrl_pin_desc; struct platform_device; struct device; @@ -194,6 +197,8 @@ struct intel_pinctrl_soc_data { size_t ncommunities; }; +const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_device *pdev); + struct intel_pad_context; struct intel_community_context; |