Pin control changes for the v7.0 kernel cycle:

Core changes:
 
 - Drop the unused devm_pinctrl_unregister() function.
 
 - Move pretended generic pin control functionality out of the
   core and into the Amlogic AM4 driver. We have something better
   coming (hopefully).
 
 New hardware support:
 
 - Spacemit K3 (RISC-V) pin control support.
 
 - Atmel AT91 PIO4 (ARM32) SAMA7D65 pin control support.
 
 - Exynos9610 (ARM64) pin control support.
 
 - Qualcomm Mahua TLMM (ARM64) pin control support.
 
 - Microchip Polarfire MSSIO (RISC-V) pin control support.
 
 - Ocelot LAN9645XF (multiplatform) pin control support.
 
 Improvements:
 
 - Using a few more guards for locking.
 
 - Various nonurgent fixes and tweaks.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAmmS7tgACgkQQRCzN7AZ
 XXMnww/+ON7+DH8YA5+yI3fPdejv+6LK4es22B3r8bPVW4HtnfGxNqC7HZ8v9SWQ
 H7BkSiEv0XLNVjKIV00WESeaK2V5MN9e52V2HfsSEDEheVdG7uA+9UVM7K2WkDnX
 zhfucJdYHa1OEwcnrWMZl+6gAMw7cjuaG3ckNzay+okNme9kiyrnjFzT7NWoCut8
 WBbzmpbMCtWdHMk7HSkPDF2LhyB7jVBbbH7qvjjrfxy1L+ybAf8tZJ6urwn+7uCZ
 dEe5YYghre2SXi4j9v+WJ+8024RaXG//7JsZvUEGs7Kb9CZAcqAdHwUiRK/rLckj
 anHoDEpall0yyH3gZA5ETn8Gw7vChAhm1CTfhUYcV9kc7/9MiShOE1UbBNvjXvCW
 e+0zixRrBp0LzJEkJD7b2NhjMLHyXS3D/uN1l5+d04uFwskttVhtQ26Icz3P/3T/
 aELNcIemwLQeAIy4btAWYu5dKE0IR80Z/nYozR7W+at9rzt9/8FleALScMXgPRMf
 HfcdKj9/cDzFNYOVtPf20gVXqSm/Yv+ZPYTpq45jKDH8U393Ly3XmNXAYOhflf+i
 Zt0KBSFf86/+u3Uo0EsQo+4JBK8FpEJT3qz6On7hXevbFiVZsXvfH0MU9up6s11d
 zfW56C4mHe0anB8y5Kc0ZKuOt4MzMJm0OOuuiZqnpnK2xFLBmlU=
 =lmwJ
 -----END PGP SIGNATURE-----

Merge tag 'pinctrl-v7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control updates from Linus Walleij:
 "Core changes:

   - Drop the unused devm_pinctrl_unregister() function

   - Move pretended generic pin control functionality out of the core
     and into the Amlogic AM4 driver. We have something better coming
     (hopefully)

  New hardware support:

   - Spacemit K3 (RISC-V) pin control support

   - Atmel AT91 PIO4 (ARM32) SAMA7D65 pin control support

   - Exynos9610 (ARM64) pin control support

   - Qualcomm Mahua TLMM (ARM64) pin control support

   - Microchip Polarfire MSSIO (RISC-V) pin control support

   - Ocelot LAN9645XF (multiplatform) pin control support

  Improvements:

   - Using a few more guards for locking

   - Various nonurgent fixes and tweaks"

* tag 'pinctrl-v7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (73 commits)
  pinctrl: generic: move function to amlogic-am4 driver
  pinctrl: intel: Align Copyright note with corporate guidelines
  pinctrl: mediatek: remove unused drv_offset field
  pinctrl: canaan: k230: Fix NULL pointer dereference when parsing devicetree
  pinctrl: single: fix refcount leak in pcs_add_gpio_func()
  pinctrl: meson: amlogic-a4: Fix device node reference leak in bank helpers
  pinctrl: qcom: sm8250-lpass-lpi: Fix i2s2_data_groups definition
  pinctrl: core: Remove duplicate error messages
  pinctrl: core: Simplify devm_pinctrl_*()
  pinctrl: core: Remove unused devm_pinctrl_unregister()
  dt-bindings: pinctrl: spacemit: fix drive-strength check warning
  pinctrl: fix kismet issues with GENERIC_PINCTRL
  pinctrl: tangier: Join tng_pinctrl_probe() into its wrapper
  pinctrl: tangier: Remove duplicate error messages
  pinctrl: lynxpoint: Remove duplicate error messages
  pinctrl: cherryview: Remove duplicate error messages
  pinctrl: baytrail: Remove duplicate error messages
  pinctrl: intel: Remove duplicate error messages
  pinctrl: equilibrium: Fix device node reference leak in pinbank_init()
  dt-bindings: pinctrl: pinctrl-microchip-sgpio: add LAN969x
  ...
This commit is contained in:
Linus Torvalds 2026-02-16 09:35:24 -08:00
commit 46a1daac56
93 changed files with 2671 additions and 497 deletions

View file

@ -106,7 +106,7 @@ patternProperties:
# the pin numbers then,
# - Finally, the name will end with either -pin or pins.
"^([rs]-)?(([a-z0-9]{3,}|[a-oq-z][a-z0-9]*?)?-)+?(p[a-ilm][0-9]*?-)??pins?$":
"^([rs]-)?(([a-z0-9]{3,}|[a-oq-z0-9][a-z0-9]*?)?-)+?(p[a-ilm][0-9]*?-)??pins?$":
type: object
properties:

View file

@ -33,7 +33,7 @@ properties:
interrupts:
description:
Specifies the interrupt lines to be used by the controller.
Each interrupt line is shared by upto 4 GPIO lines.
Each interrupt line is shared by up to 4 GPIO lines.
maxItems: 8
interrupt-controller: true

View file

@ -0,0 +1,109 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/microchip,mpfs-pinctrl-mssio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip Polarfire SoC MSSIO pinctrl
maintainers:
- Conor Dooley <conor.dooley@microchip.com>
properties:
compatible:
oneOf:
- const: microchip,mpfs-pinctrl-mssio
- items:
- const: microchip,pic64gx-pinctrl-mssio
- const: microchip,mpfs-pinctrl-mssio
reg:
maxItems: 1
pinctrl-use-default: true
patternProperties:
'-cfg$':
type: object
additionalProperties: false
patternProperties:
'-pins$':
type: object
additionalProperties: false
allOf:
- $ref: pincfg-node.yaml#
- $ref: pinmux-node.yaml#
properties:
pins:
description:
The list of IOs that properties in the pincfg node apply to.
function:
description:
A string containing the name of the function to mux for these
pins. The "reserved" function tristates a pin.
enum: [ sd, emmc, qspi, spi, usb, uart, i2c, can, mdio, misc
reserved, gpio, fabric-test, tied-low, tied-high, tristate ]
bias-bus-hold: true
bias-disable: true
bias-pull-down: true
bias-pull-up: true
input-schmitt-enable: true
low-power-enable: true
drive-strength:
enum: [ 2, 4, 6, 8, 10, 12, 16, 20 ]
power-source:
description:
Which bank voltage to use. This cannot differ for pins in a
given bank, the whole bank uses the same voltage.
enum: [ 1200000, 1500000, 1800000, 2500000, 3300000 ]
microchip,clamp-diode:
$ref: /schemas/types.yaml#/definitions/flag
description:
Reflects the "Clamp Diode" setting in the MSS Configurator for
this pin. This setting controls whether or not input voltage
clamping should be enabled.
microchip,ibufmd:
$ref: /schemas/types.yaml#/definitions/uint32
default: 0
description:
Reflects the "IBUFMD" bits in the MSS Configurator output files
for this pin.
required:
- pins
- function
- power-source
required:
- compatible
- reg
additionalProperties: false
examples:
- |
pinctrl@204 {
compatible = "microchip,mpfs-pinctrl-mssio";
reg = <0x204 0x7c>;
ikrd-spi1-cfg {
spi1-pins {
pins = <30>, <31>, <32>, <33>;
function = "spi";
bias-pull-up;
drive-strength = <8>;
power-source = <3300000>;
microchip,ibufmd = <0x1>;
};
};
};
...

View file

@ -21,10 +21,15 @@ properties:
pattern: '^gpio@[0-9a-f]+$'
compatible:
enum:
- microchip,sparx5-sgpio
- mscc,ocelot-sgpio
- mscc,luton-sgpio
oneOf:
- enum:
- microchip,sparx5-sgpio
- mscc,ocelot-sgpio
- mscc,luton-sgpio
- items:
- enum:
- microchip,lan9691-sgpio
- const: microchip,sparx5-sgpio
'#address-cells':
const: 1
@ -80,7 +85,12 @@ patternProperties:
type: object
properties:
compatible:
const: microchip,sparx5-sgpio-bank
oneOf:
- items:
- enum:
- microchip,lan9691-sgpio-bank
- const: microchip,sparx5-sgpio-bank
- const: microchip,sparx5-sgpio-bank
reg:
description: |

View file

@ -14,6 +14,7 @@ properties:
compatible:
oneOf:
- enum:
- microchip,lan96455f-pinctrl
- microchip,lan966x-pinctrl
- microchip,lan9691-pinctrl
- microchip,sparx5-pinctrl
@ -30,6 +31,11 @@ properties:
- microchip,lan9693-pinctrl
- microchip,lan9692-pinctrl
- const: microchip,lan9691-pinctrl
- items:
- enum:
- microchip,lan96457f-pinctrl
- microchip,lan96459f-pinctrl
- const: microchip,lan96455f-pinctrl
reg:
items:

View file

@ -10,14 +10,16 @@ maintainers:
- Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
description:
Top Level Mode Multiplexer pin controller in Qualcomm Glymur SoC.
Top Level Mode Multiplexer pin controller in Qualcomm Glymur and Mahua SoC.
allOf:
- $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
properties:
compatible:
const: qcom,glymur-tlmm
enum:
- qcom,glymur-tlmm
- qcom,mahua-tlmm
reg:
maxItems: 1

View file

@ -49,6 +49,17 @@ properties:
gpio-ranges:
maxItems: 1
interrupt-controller: true
'#interrupt-cells':
const: 2
description:
The first cell contains the global GPIO port index, constructed using the
RZT2H_GPIO() helper macro from <dt-bindings/pinctrl/renesas,r9a09g077-pinctrl.h>
and the second cell is used to specify the flag.
E.g. "interrupts = <RZT2H_GPIO(8, 6) IRQ_TYPE_EDGE_FALLING>;" if P08_6 is
being used as an interrupt.
clocks:
maxItems: 1
@ -139,6 +150,8 @@ examples:
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pinctrl 0 0 288>;
interrupt-controller;
#interrupt-cells = <2>;
power-domains = <&cpg>;
serial0-pins {

View file

@ -48,6 +48,7 @@ properties:
- enum:
- google,gs101-wakeup-eint
- samsung,exynos2200-wakeup-eint
- samsung,exynos9610-wakeup-eint
- samsung,exynos9810-wakeup-eint
- samsung,exynos990-wakeup-eint
- samsung,exynosautov9-wakeup-eint

View file

@ -55,6 +55,7 @@ properties:
- samsung,exynos850-pinctrl
- samsung,exynos8890-pinctrl
- samsung,exynos8895-pinctrl
- samsung,exynos9610-pinctrl
- samsung,exynos9810-pinctrl
- samsung,exynos990-pinctrl
- samsung,exynosautov9-pinctrl

View file

@ -11,7 +11,9 @@ maintainers:
properties:
compatible:
const: spacemit,k1-pinctrl
enum:
- spacemit,k1-pinctrl
- spacemit,k3-pinctrl
reg:
items:
@ -30,6 +32,10 @@ properties:
resets:
maxItems: 1
spacemit,apbc:
$ref: /schemas/types.yaml#/definitions/phandle
description: Phandle to syscon that access the protected register
patternProperties:
'-cfg$':
type: object
@ -72,10 +78,20 @@ patternProperties:
enum: [ 0, 1 ]
drive-strength:
description: |
typical current when output high level.
1.8V output: 11, 21, 32, 42 (mA)
3.3V output: 7, 10, 13, 16, 19, 23, 26, 29 (mA)
description:
typical current (in mA) when the output at high level.
anyOf:
- enum: [ 11, 21, 32, 42 ]
description: For K1 SoC, 1.8V voltage output
- enum: [ 7, 10, 13, 16, 19, 23, 26, 29 ]
description: For K1 SoC, 3.3V voltage output
- enum: [ 2, 4, 6, 7, 9, 11, 13, 14, 21, 23, 25, 26, 28, 30, 31, 33 ]
description: For K3 SoC, 1.8V voltage output
- enum: [ 3, 5, 7, 9, 11, 13, 15, 17, 25, 27, 29, 31, 33, 35, 37, 38 ]
description: For K3 SoC, 3.3V voltage output
input-schmitt:
description: |
@ -126,6 +142,7 @@ examples:
clocks = <&syscon_apbc 42>,
<&syscon_apbc 94>;
clock-names = "func", "bus";
spacemit,apbc = <&syscon_apbc>;
uart0_2_cfg: uart0-2-cfg {
uart0-2-pins {

View file

@ -42,6 +42,10 @@ properties:
type: object
$ref: /schemas/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml
pinctrl@204:
type: object
$ref: /schemas/pinctrl/microchip,mpfs-pinctrl-mssio.yaml
required:
- compatible
- reg

View file

@ -408,7 +408,6 @@ PINCTRL
devm_pinctrl_get_select()
devm_pinctrl_register()
devm_pinctrl_register_and_init()
devm_pinctrl_unregister()
POWER
devm_reboot_mode_register()

View file

@ -22666,6 +22666,7 @@ F: Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml
F: Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml
F: Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
F: Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml
F: Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-mssio.yaml
F: Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml
F: Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
F: Documentation/devicetree/bindings/riscv/microchip.yaml
@ -22680,8 +22681,9 @@ F: drivers/gpio/gpio-mpfs.c
F: drivers/i2c/busses/i2c-microchip-corei2c.c
F: drivers/mailbox/mailbox-mpfs.c
F: drivers/pci/controller/plda/pcie-microchip-host.c
F: drivers/pinctrl/pinctrl-mpfs-iomux0.c
F: drivers/pinctrl/pinctrl-pic64gx-gpio2.c
F: drivers/pinctrl/microchip/pinctrl-mpfs-iomux0.c
F: drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c
F: drivers/pinctrl/microchip/pinctrl-pic64gx-gpio2.c
F: drivers/pwm/pwm-microchip-core.c
F: drivers/reset/reset-mpfs.c
F: drivers/rtc/rtc-mpfs.c

View file

@ -302,3 +302,12 @@ static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
void software_node_notify(struct device *dev);
void software_node_notify_remove(struct device *dev);
#ifdef CONFIG_PINCTRL
int pinctrl_bind_pins(struct device *dev);
#else
static inline int pinctrl_bind_pins(struct device *dev)
{
return 0;
}
#endif /* CONFIG_PINCTRL */

View file

@ -14,6 +14,8 @@
#include <linux/pinctrl/consumer.h>
#include <linux/slab.h>
#include "base.h"
/**
* pinctrl_bind_pins() - called by the device core before probe
* @dev: the device that is just about to probe

View file

@ -25,6 +25,12 @@ config GENERIC_PINCONF
bool
select PINCONF
config GENERIC_PINCTRL
bool
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
config DEBUG_PINCTRL
bool "Debug PINCTRL calls"
depends on DEBUG_KERNEL
@ -486,16 +492,6 @@ config PINCTRL_PIC32MZDA
def_bool y if PIC32MZDA
select PINCTRL_PIC32
config PINCTRL_PIC64GX
bool "pic64gx gpio2 pinctrl driver"
depends on ARCH_MICROCHIP || COMPILE_TEST
depends on OF
select GENERIC_PINCONF
select REGMAP_MMIO
default y
help
This selects the pinctrl driver for gpio2 on pic64gx.
config PINCTRL_PISTACHIO
bool "IMG Pistachio SoC pinctrl driver"
depends on OF && (MIPS || COMPILE_TEST)
@ -507,15 +503,6 @@ config PINCTRL_PISTACHIO
help
This support pinctrl and GPIO driver for IMG Pistachio SoC.
config PINCTRL_POLARFIRE_SOC
bool "Polarfire SoC pinctrl driver"
depends on ARCH_MICROCHIP || COMPILE_TEST
depends on OF
select GENERIC_PINCONF
default y
help
This selects the pinctrl driver for Microchip Polarfire SoC.
config PINCTRL_RK805
tristate "Pinctrl and GPIO driver for RK805 PMIC"
depends on MFD_RK8XX
@ -710,6 +697,7 @@ source "drivers/pinctrl/freescale/Kconfig"
source "drivers/pinctrl/intel/Kconfig"
source "drivers/pinctrl/mediatek/Kconfig"
source "drivers/pinctrl/meson/Kconfig"
source "drivers/pinctrl/microchip/Kconfig"
source "drivers/pinctrl/mvebu/Kconfig"
source "drivers/pinctrl/nomadik/Kconfig"
source "drivers/pinctrl/nuvoton/Kconfig"

View file

@ -7,6 +7,7 @@ obj-y += core.o pinctrl-utils.o
obj-$(CONFIG_PINMUX) += pinmux.o
obj-$(CONFIG_PINCONF) += pinconf.o
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_GENERIC_PINCTRL) += pinctrl-generic.o
obj-$(CONFIG_OF) += devicetree.o
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
@ -48,9 +49,7 @@ obj-$(CONFIG_PINCTRL_OCELOT) += pinctrl-ocelot.o
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
obj-$(CONFIG_PINCTRL_PEF2256) += pinctrl-pef2256.o
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
obj-$(CONFIG_PINCTRL_PIC64GX) += pinctrl-pic64gx-gpio2.o
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
obj-$(CONFIG_PINCTRL_POLARFIRE_SOC) += pinctrl-mpfs-iomux0.o
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
obj-$(CONFIG_PINCTRL_RP1) += pinctrl-rp1.o
@ -76,6 +75,7 @@ obj-y += freescale/
obj-$(CONFIG_X86) += intel/
obj-y += mediatek/
obj-$(CONFIG_PINCTRL_MESON) += meson/
obj-y += microchip/
obj-y += mvebu/
obj-y += nomadik/
obj-y += nuvoton/

View file

@ -6,14 +6,12 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/string.h>
#include <linux/types.h>
#include "../core.h"

View file

@ -7,14 +7,13 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/mutex.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/string.h>
#include <linux/types.h>
#include "../core.h"
@ -2654,9 +2653,7 @@ static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx,
np = of_parse_phandle(ctx->dev->of_node,
"aspeed,external-nodes", 1);
if (np) {
if (!of_device_is_compatible(np->parent, "aspeed,ast2400-lpc-v2") &&
!of_device_is_compatible(np->parent, "aspeed,ast2500-lpc-v2") &&
!of_device_is_compatible(np->parent, "aspeed,ast2600-lpc-v2"))
if (!of_device_is_compatible(np->parent, "aspeed,ast2500-lpc-v2"))
return ERR_PTR(-ENODEV);
map = syscon_node_to_regmap(np->parent);

View file

@ -4,13 +4,10 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/string.h>
#include <linux/types.h>
#include "../core.h"

View file

@ -1383,9 +1383,9 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
}
EXPORT_SYMBOL_GPL(pinctrl_select_state);
static void devm_pinctrl_release(struct device *dev, void *res)
static void devm_pinctrl_release(void *p)
{
pinctrl_put(*(struct pinctrl **)res);
pinctrl_put(p);
}
/**
@ -1397,31 +1397,21 @@ static void devm_pinctrl_release(struct device *dev, void *res)
*/
struct pinctrl *devm_pinctrl_get(struct device *dev)
{
struct pinctrl **ptr, *p;
ptr = devres_alloc(devm_pinctrl_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
struct pinctrl *p;
int ret;
p = pinctrl_get(dev);
if (!IS_ERR(p)) {
*ptr = p;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
if (IS_ERR(p))
return p;
ret = devm_add_action_or_reset(dev, devm_pinctrl_release, p);
if (ret)
return ERR_PTR(ret);
return p;
}
EXPORT_SYMBOL_GPL(devm_pinctrl_get);
static int devm_pinctrl_match(struct device *dev, void *res, void *data)
{
struct pinctrl **p = res;
return *p == data;
}
/**
* devm_pinctrl_put() - Resource managed pinctrl_put()
* @p: the pinctrl handle to release
@ -1432,8 +1422,7 @@ static int devm_pinctrl_match(struct device *dev, void *res, void *data)
*/
void devm_pinctrl_put(struct pinctrl *p)
{
WARN_ON(devres_release(p->dev, devm_pinctrl_release,
devm_pinctrl_match, p));
devm_release_action(p->dev, devm_pinctrl_release, p);
}
EXPORT_SYMBOL_GPL(devm_pinctrl_put);
@ -2198,10 +2187,8 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
int error;
error = pinctrl_claim_hogs(pctldev);
if (error) {
dev_err(pctldev->dev, "could not claim hogs: %i\n", error);
if (error)
return error;
}
mutex_lock(&pinctrldev_list_mutex);
list_add_tail(&pctldev->node, &pinctrldev_list);
@ -2316,23 +2303,11 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
}
EXPORT_SYMBOL_GPL(pinctrl_unregister);
static void devm_pinctrl_dev_release(struct device *dev, void *res)
static void devm_pinctrl_dev_release(void *pctldev)
{
struct pinctrl_dev *pctldev = *(struct pinctrl_dev **)res;
pinctrl_unregister(pctldev);
}
static int devm_pinctrl_dev_match(struct device *dev, void *res, void *data)
{
struct pctldev **r = res;
if (WARN_ON(!r || !*r))
return 0;
return *r == data;
}
/**
* devm_pinctrl_register() - Resource managed version of pinctrl_register().
* @dev: parent device for this pin controller
@ -2348,20 +2323,16 @@ struct pinctrl_dev *devm_pinctrl_register(struct device *dev,
const struct pinctrl_desc *pctldesc,
void *driver_data)
{
struct pinctrl_dev **ptr, *pctldev;
ptr = devres_alloc(devm_pinctrl_dev_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
struct pinctrl_dev *pctldev;
int ret;
pctldev = pinctrl_register(pctldesc, dev, driver_data);
if (IS_ERR(pctldev)) {
devres_free(ptr);
if (IS_ERR(pctldev))
return pctldev;
}
*ptr = pctldev;
devres_add(dev, ptr);
ret = devm_add_action_or_reset(dev, devm_pinctrl_dev_release, pctldev);
if (ret)
return ERR_PTR(ret);
return pctldev;
}
@ -2383,38 +2354,16 @@ int devm_pinctrl_register_and_init(struct device *dev,
void *driver_data,
struct pinctrl_dev **pctldev)
{
struct pinctrl_dev **ptr;
int error;
ptr = devres_alloc(devm_pinctrl_dev_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return -ENOMEM;
error = pinctrl_register_and_init(pctldesc, dev, driver_data, pctldev);
if (error) {
devres_free(ptr);
if (error)
return error;
}
*ptr = *pctldev;
devres_add(dev, ptr);
return 0;
return devm_add_action_or_reset(dev, devm_pinctrl_dev_release, *pctldev);
}
EXPORT_SYMBOL_GPL(devm_pinctrl_register_and_init);
/**
* devm_pinctrl_unregister() - Resource managed version of pinctrl_unregister().
* @dev: device for which resource was allocated
* @pctldev: the pinctrl device to unregister.
*/
void devm_pinctrl_unregister(struct device *dev, struct pinctrl_dev *pctldev)
{
WARN_ON(devres_release(dev, devm_pinctrl_dev_release,
devm_pinctrl_dev_match, pctldev));
}
EXPORT_SYMBOL_GPL(devm_pinctrl_unregister);
static int __init pinctrl_init(void)
{
pr_debug("initialized pinctrl subsystem\n");

View file

@ -38,11 +38,12 @@ struct scmi_pinctrl_imx {
};
/* SCMI pin control types, aligned with SCMI firmware */
#define IMX_SCMI_NUM_CFG 4
#define IMX_SCMI_NUM_CFG 5
#define IMX_SCMI_PIN_MUX 192
#define IMX_SCMI_PIN_CONFIG 193
#define IMX_SCMI_PIN_DAISY_ID 194
#define IMX_SCMI_PIN_DAISY_CFG 195
#define IMX_SCMI_PIN_EXT 196
#define IMX_SCMI_NO_PAD_CTL BIT(31)
#define IMX_SCMI_PAD_SION BIT(30)
@ -50,8 +51,9 @@ struct scmi_pinctrl_imx {
#define IMX_SCMI_PIN_SIZE 24
#define IMX95_DAISY_OFF 0x408
#define IMX94_DAISY_OFF 0x608
#define IMX95_DAISY_OFF 0x408
#define IMX952_DAISY_OFF 0x460
static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
@ -73,6 +75,8 @@ static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev,
daisy_off = IMX95_DAISY_OFF;
} else if (of_machine_is_compatible("fsl,imx94")) {
daisy_off = IMX94_DAISY_OFF;
} else if (of_machine_is_compatible("fsl,imx952")) {
daisy_off = IMX952_DAISY_OFF;
} else {
dev_err(pctldev->dev, "platform not support scmi pinctrl\n");
return -EINVAL;
@ -118,7 +122,14 @@ static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev,
pin_id = mux_reg / 4;
cfg[j++] = pinconf_to_config_packed(IMX_SCMI_PIN_MUX, mux_val);
cfg[j++] = pinconf_to_config_packed(IMX_SCMI_PIN_MUX, (mux_val & 0xFF));
if (mux_val & 0xFF00) {
int ext_val = (mux_val & 0xFF00) >> 8;
cfg[j++] = pinconf_to_config_packed(IMX_SCMI_PIN_EXT, ext_val);
} else
ncfg--;
if (!conf_reg || (conf_val & IMX_SCMI_NO_PAD_CTL))
ncfg--;
@ -291,8 +302,9 @@ scmi_pinctrl_imx_get_pins(struct scmi_pinctrl_imx *pmx, struct pinctrl_desc *des
}
static const char * const scmi_pinctrl_imx_allowlist[] = {
"fsl,imx95",
"fsl,imx94",
"fsl,imx95",
"fsl,imx952",
NULL
};

View file

@ -45,6 +45,7 @@ config PINCTRL_INTEL_PLATFORM
of Intel PCH pins and using them as GPIOs. Currently the following
Intel SoCs / platforms require this to be functional:
- Lunar Lake
- Nova Lake
- Panther Lake
config PINCTRL_ALDERLAKE
@ -52,7 +53,10 @@ config PINCTRL_ALDERLAKE
select PINCTRL_INTEL
help
This pinctrl driver provides an interface that allows configuring
of Intel Alder Lake PCH pins and using them as GPIOs.
PCH pins of the following platforms and using them as GPIOs:
- Alder Lake HX, N, and S
- Raptor Lake HX, E, and S
- Twin Lake
config PINCTRL_BROXTON
tristate "Intel Broxton pinctrl and GPIO driver"
@ -136,15 +140,17 @@ config PINCTRL_METEORLAKE
select PINCTRL_INTEL
help
This pinctrl driver provides an interface that allows configuring
of Intel Meteor Lake pins and using them as GPIOs.
SoC pins of the following platforms and using them as GPIOs:
- Arrow Lake (all variants)
- Meteor Lake (all variants)
config PINCTRL_METEORPOINT
tristate "Intel Meteor Point pinctrl and GPIO driver"
select PINCTRL_INTEL
help
Meteor Point is the PCH of Intel Meteor Lake. This pinctrl driver
provides an interface that allows configuring of PCH pins and
using them as GPIOs.
This pinctrl driver provides an interface that allows configuring
PCH pins of the following platforms and using them as GPIOs:
- Arrow Lake HX and S
config PINCTRL_SUNRISEPOINT
tristate "Intel Sunrisepoint pinctrl and GPIO driver"
@ -159,7 +165,11 @@ config PINCTRL_TIGERLAKE
select PINCTRL_INTEL
help
This pinctrl driver provides an interface that allows configuring
of Intel Tiger Lake PCH pins and using them as GPIOs.
PCH pins of the following platforms and using them as GPIOs:
- Alder Lake H, P, PS, and U
- Raptor Lake H, P, PS, PX, and U
- Rocket Lake S
- Tiger Lake (all variants)
source "drivers/pinctrl/intel/Kconfig.tng"
endmenu

View file

@ -2,7 +2,7 @@
/*
* Intel Alder Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2020, 2022 Intel Corporation
* Copyright (C) 2020-2022 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Pinctrl GPIO driver for Intel Baytrail
*
* Copyright (c) 2012-2013, Intel Corporation
* Copyright (C) 2012-2013 Intel Corporation
* Author: Mathias Nyman <mathias.nyman@linux.intel.com>
*/
@ -101,10 +101,12 @@ struct intel_pad_context {
u32 val;
};
#define COMMUNITY(p, n, map) \
#define BYT_COMMUNITY(p, n, g, map) \
{ \
.pin_base = (p), \
.npins = (n), \
.gpps = (g), \
.ngpps = ARRAY_SIZE(g), \
.pad_map = (map),\
}
@ -360,8 +362,15 @@ static const struct intel_function byt_score_functions[] = {
FUNCTION("gpio", byt_score_gpio_groups),
};
static const struct intel_padgroup byt_score_gpps[] = {
INTEL_GPP(0, 0, 31, 0),
INTEL_GPP(1, 32, 63, 32),
INTEL_GPP(2, 64, 95, 64),
INTEL_GPP(3, 96, 101, 96),
};
static const struct intel_community byt_score_communities[] = {
COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
BYT_COMMUNITY(0, 102, byt_score_gpps, byt_score_pins_map),
};
static const struct intel_pinctrl_soc_data byt_score_soc_data = {
@ -483,8 +492,13 @@ static const struct intel_function byt_sus_functions[] = {
FUNCTION("pmu_clk", byt_sus_pmu_clk_groups),
};
static const struct intel_padgroup byt_sus_gpps[] = {
INTEL_GPP(0, 0, 31, 0),
INTEL_GPP(1, 32, 43, 32),
};
static const struct intel_community byt_sus_communities[] = {
COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
BYT_COMMUNITY(0, 44, byt_sus_gpps, byt_sus_pins_map),
};
static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
@ -536,8 +550,12 @@ static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
3, 6, 10, 13, 2, 5, 9, 7,
};
static const struct intel_padgroup byt_ncore_gpps[] = {
INTEL_GPP(0, 0, 27, 0),
};
static const struct intel_community byt_ncore_communities[] = {
COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
BYT_COMMUNITY(0, 28, byt_ncore_gpps, byt_ncore_pins_map),
};
static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
@ -1490,19 +1508,6 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
return 0;
}
static int byt_gpio_add_pin_ranges(struct gpio_chip *chip)
{
struct intel_pinctrl *vg = gpiochip_get_data(chip);
struct device *dev = vg->dev;
int ret;
ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins);
if (ret)
return dev_err_probe(dev, ret, "failed to add GPIO pin range\n");
return 0;
}
static int byt_gpio_probe(struct intel_pinctrl *vg)
{
struct platform_device *pdev = to_platform_device(vg->dev);
@ -1515,7 +1520,7 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
gc->label = dev_name(vg->dev);
gc->base = -1;
gc->can_sleep = false;
gc->add_pin_ranges = byt_gpio_add_pin_ranges;
gc->add_pin_ranges = intel_gpio_add_pin_ranges;
gc->parent = vg->dev;
gc->ngpio = vg->soc->npins;
@ -1611,7 +1616,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg);
if (IS_ERR(vg->pctldev))
return dev_err_probe(dev, PTR_ERR(vg->pctldev), "failed to register pinctrl\n");
return PTR_ERR(vg->pctldev);
ret = byt_gpio_probe(vg);
if (ret)

View file

@ -2,7 +2,7 @@
/*
* Intel Broxton SoC pinctrl/GPIO driver
*
* Copyright (C) 2015, 2016 Intel Corporation
* Copyright (C) 2015-2016 Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Cannon Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2017, Intel Corporation
* Copyright (C) 2017 Intel Corporation
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Cedar Fork PCH pinctrl/GPIO driver
*
* Copyright (C) 2017, Intel Corporation
* Copyright (C) 2017 Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Cherryview/Braswell pinctrl driver
*
* Copyright (C) 2014, 2020 Intel Corporation
* Copyright (C) 2014-2020 Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*
* This driver is based on the original Cherryview GPIO driver by
@ -1644,7 +1644,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl);
if (IS_ERR(pctrl->pctldev))
return dev_err_probe(dev, PTR_ERR(pctrl->pctldev), "failed to register pinctrl\n");
return PTR_ERR(pctrl->pctldev);
ret = chv_gpio_probe(pctrl, irq);
if (ret)

View file

@ -2,7 +2,7 @@
/*
* Intel Denverton SoC pinctrl/GPIO driver
*
* Copyright (C) 2017, Intel Corporation
* Copyright (C) 2017 Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Elkhart Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2019, Intel Corporation
* Copyright (C) 2019 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Emmitsburg PCH pinctrl/GPIO driver
*
* Copyright (C) 2020, Intel Corporation
* Copyright (C) 2020 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Ice Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2018, 2022 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel PCH pinctrl/GPIO driver
*
* Copyright (C) 2021-2023, Intel Corporation
* Copyright (C) 2021-2023 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel pinctrl/GPIO core driver.
*
* Copyright (C) 2015, Intel Corporation
* Copyright (C) 2015 Intel Corporation
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/
@ -1673,7 +1673,7 @@ int intel_pinctrl_probe(struct platform_device *pdev,
pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl);
if (IS_ERR(pctrl->pctldev))
return dev_err_probe(dev, PTR_ERR(pctrl->pctldev), "failed to register pinctrl\n");
return PTR_ERR(pctrl->pctldev);
ret = intel_gpio_probe(pctrl, irq);
if (ret)

View file

@ -2,7 +2,7 @@
/*
* Core pinctrl/GPIO driver for Intel GPIO controllers
*
* Copyright (C) 2015, Intel Corporation
* Copyright (C) 2015 Intel Corporation
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Jasper Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2020, Intel Corporation
* Copyright (C) 2020 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Lakefield PCH pinctrl/GPIO driver
*
* Copyright (C) 2020, Intel Corporation
* Copyright (C) 2020 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Lewisburg pinctrl/GPIO driver
*
* Copyright (C) 2017, Intel Corporation
* Copyright (C) 2017 Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Lynxpoint PCH pinctrl/GPIO driver
*
* Copyright (c) 2012, 2019, Intel Corporation
* Copyright (C) 2012-2019 Intel Corporation
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
* Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/
@ -29,10 +29,12 @@
#include "pinctrl-intel.h"
#define COMMUNITY(p, n) \
#define LPTLP_COMMUNITY(p, n, g) \
{ \
.pin_base = (p), \
.npins = (n), \
.gpps = (g), \
.ngpps = ARRAY_SIZE(g), \
}
static const struct pinctrl_pin_desc lptlp_pins[] = {
@ -133,8 +135,14 @@ static const struct pinctrl_pin_desc lptlp_pins[] = {
PINCTRL_PIN(94, "GP94_UART0_CTSB"),
};
static const struct intel_padgroup lptlp_gpps[] = {
INTEL_GPP(0, 0, 31, 0),
INTEL_GPP(1, 32, 63, 32),
INTEL_GPP(2, 64, 94, 64),
};
static const struct intel_community lptlp_communities[] = {
COMMUNITY(0, 95),
LPTLP_COMMUNITY(0, 95, lptlp_gpps),
};
static const struct intel_pinctrl_soc_data lptlp_soc_data = {
@ -692,19 +700,6 @@ static int lp_gpio_irq_init_hw(struct gpio_chip *chip)
return 0;
}
static int lp_gpio_add_pin_ranges(struct gpio_chip *chip)
{
struct intel_pinctrl *lg = gpiochip_get_data(chip);
struct device *dev = lg->dev;
int ret;
ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, lg->soc->npins);
if (ret)
return dev_err_probe(dev, ret, "failed to add GPIO pin range\n");
return 0;
}
static int lp_gpio_probe(struct platform_device *pdev)
{
const struct intel_pinctrl_soc_data *soc;
@ -740,7 +735,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
lg->pctldev = devm_pinctrl_register(dev, &lg->pctldesc, lg);
if (IS_ERR(lg->pctldev))
return dev_err_probe(dev, PTR_ERR(lg->pctldev), "failed to register pinctrl\n");
return PTR_ERR(lg->pctldev);
platform_set_drvdata(pdev, lg);
@ -777,7 +772,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
gc->base = -1;
gc->ngpio = LP_NUM_GPIO;
gc->can_sleep = false;
gc->add_pin_ranges = lp_gpio_add_pin_ranges;
gc->add_pin_ranges = intel_gpio_add_pin_ranges;
gc->parent = dev;
/* set up interrupts */

View file

@ -2,7 +2,7 @@
/*
* Intel Merrifield SoC pinctrl driver
*
* Copyright (C) 2016, Intel Corporation
* Copyright (C) 2016 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Meteor Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2022, Intel Corporation
* Copyright (C) 2022 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Meteor Point PCH pinctrl/GPIO driver
*
* Copyright (C) 2022-2023, Intel Corporation
* Copyright (C) 2022-2023 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Moorefield SoC pinctrl driver
*
* Copyright (C) 2022, Intel Corporation
* Copyright (C) 2022 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Sunrisepoint PCH pinctrl/GPIO driver
*
* Copyright (C) 2015, Intel Corporation
* Copyright (C) 2015 Intel Corporation
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/

View file

@ -2,7 +2,7 @@
/*
* Intel Tangier pinctrl driver
*
* Copyright (C) 2016, 2023 Intel Corporation
* Copyright (C) 2016-2023 Intel Corporation
*
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
* Raag Jadav <raag.jadav@intel.com>
@ -518,15 +518,19 @@ static const struct pinctrl_desc tng_pinctrl_desc = {
.owner = THIS_MODULE,
};
static int tng_pinctrl_probe(struct platform_device *pdev,
const struct tng_pinctrl *data)
int devm_tng_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct tng_pinctrl *data;
struct tng_family *families;
struct tng_pinctrl *tp;
void __iomem *regs;
unsigned int i;
data = device_get_match_data(dev);
if (!data)
return -ENODATA;
tp = devm_kmemdup(dev, data, sizeof(*data), GFP_KERNEL);
if (!tp)
return -ENOMEM;
@ -562,21 +566,10 @@ static int tng_pinctrl_probe(struct platform_device *pdev,
tp->pctldev = devm_pinctrl_register(dev, &tp->pctldesc, tp);
if (IS_ERR(tp->pctldev))
return dev_err_probe(dev, PTR_ERR(tp->pctldev), "failed to register pinctrl\n");
return PTR_ERR(tp->pctldev);
return 0;
}
int devm_tng_pinctrl_probe(struct platform_device *pdev)
{
const struct tng_pinctrl *data;
data = device_get_match_data(&pdev->dev);
if (!data)
return -ENODATA;
return tng_pinctrl_probe(pdev, data);
}
EXPORT_SYMBOL_NS_GPL(devm_tng_pinctrl_probe, "PINCTRL_TANGIER");
MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");

View file

@ -2,7 +2,7 @@
/*
* Intel Tangier pinctrl functions
*
* Copyright (C) 2016, 2023 Intel Corporation
* Copyright (C) 2016-2023 Intel Corporation
*
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
* Raag Jadav <raag.jadav@intel.com>

View file

@ -2,7 +2,7 @@
/*
* Intel Tiger Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2019 - 2020, Intel Corporation
* Copyright (C) 2019-2020 Intel Corporation
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/

View file

@ -544,24 +544,32 @@ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin)
}
}
eint->pin_list = devm_kmalloc(eint->dev, eint->nbase * sizeof(u16 *), GFP_KERNEL);
eint->pin_list = devm_kcalloc(eint->dev, eint->nbase,
sizeof(*eint->pin_list), GFP_KERNEL);
if (!eint->pin_list)
goto err_pin_list;
eint->wake_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
eint->wake_mask = devm_kcalloc(eint->dev, eint->nbase,
sizeof(*eint->wake_mask), GFP_KERNEL);
if (!eint->wake_mask)
goto err_wake_mask;
eint->cur_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
eint->cur_mask = devm_kcalloc(eint->dev, eint->nbase,
sizeof(*eint->cur_mask), GFP_KERNEL);
if (!eint->cur_mask)
goto err_cur_mask;
for (i = 0; i < eint->nbase; i++) {
eint->pin_list[i] = devm_kzalloc(eint->dev, eint->base_pin_num[i] * sizeof(u16),
eint->pin_list[i] = devm_kzalloc(eint->dev,
eint->base_pin_num[i] * sizeof(**eint->pin_list),
GFP_KERNEL);
port = DIV_ROUND_UP(eint->base_pin_num[i], 32);
eint->wake_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
eint->cur_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
eint->wake_mask[i] = devm_kzalloc(eint->dev,
port * sizeof(**eint->wake_mask),
GFP_KERNEL);
eint->cur_mask[i] = devm_kzalloc(eint->dev,
port * sizeof(**eint->cur_mask),
GFP_KERNEL);
if (!eint->pin_list[i] || !eint->wake_mask[i] || !eint->cur_mask[i])
goto err_eint;
}
@ -597,12 +605,9 @@ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin)
err_eint:
for (i = 0; i < eint->nbase; i++) {
if (eint->cur_mask[i])
devm_kfree(eint->dev, eint->cur_mask[i]);
if (eint->wake_mask[i])
devm_kfree(eint->dev, eint->wake_mask[i]);
if (eint->pin_list[i])
devm_kfree(eint->dev, eint->pin_list[i]);
devm_kfree(eint->dev, eint->cur_mask[i]);
devm_kfree(eint->dev, eint->wake_mask[i]);
devm_kfree(eint->dev, eint->pin_list[i]);
}
devm_kfree(eint->dev, eint->cur_mask);
err_cur_mask:

View file

@ -1019,7 +1019,7 @@ static struct mtk_pin_soc mt7981_data = {
.nfuncs = ARRAY_SIZE(mt7981_functions),
.eint_hw = &mt7981_eint_hw,
.gpio_m = 0,
.ies_present = false,
.ies_present = true,
.base_names = mt7981_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,

View file

@ -919,7 +919,7 @@ static struct mtk_pin_soc mt7986a_data = {
.nfuncs = ARRAY_SIZE(mt7986_functions),
.eint_hw = &mt7986a_eint_hw,
.gpio_m = 0,
.ies_present = false,
.ies_present = true,
.base_names = mt7986_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
@ -945,7 +945,7 @@ static struct mtk_pin_soc mt7986b_data = {
.nfuncs = ARRAY_SIZE(mt7986_functions),
.eint_hw = &mt7986b_eint_hw,
.gpio_m = 0,
.ies_present = false,
.ies_present = true,
.base_names = mt7986_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,

View file

@ -1505,7 +1505,7 @@ static const struct mtk_pin_soc mt7988_data = {
.nfuncs = ARRAY_SIZE(mt7988_functions),
.eint_hw = &mt7988_eint_hw,
.gpio_m = 0,
.ies_present = false,
.ies_present = true,
.base_names = mt7988_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,

View file

@ -456,7 +456,6 @@ static const struct mtk_pinctrl_devdata mt8365_pinctrl_data = {
.smt_offset = 0x0470,
.pullen_offset = 0x0860,
.pullsel_offset = 0x0900,
.drv_offset = 0x0710,
.type1_start = 145,
.type1_end = 145,
.port_shf = 4,

View file

@ -263,7 +263,6 @@ struct mtk_pinctrl_devdata {
unsigned int smt_offset;
unsigned int pullen_offset;
unsigned int pullsel_offset;
unsigned int drv_offset;
unsigned int dout_offset;
unsigned int din_offset;
unsigned int pinmux_offset;

View file

@ -15,25 +15,25 @@ if PINCTRL_MESON
config PINCTRL_MESON8
bool "Meson 8 SoC pinctrl driver"
depends on ARM
depends on ARM || COMPILE_TEST
select PINCTRL_MESON8_PMX
default ARCH_MESON
config PINCTRL_MESON8B
bool "Meson 8b SoC pinctrl driver"
depends on ARM
depends on ARM || COMPILE_TEST
select PINCTRL_MESON8_PMX
default ARCH_MESON
config PINCTRL_MESON_GXBB
tristate "Meson gxbb SoC pinctrl driver"
depends on ARM64
depends on ARM64 || COMPILE_TEST
select PINCTRL_MESON8_PMX
default ARCH_MESON
config PINCTRL_MESON_GXL
tristate "Meson gxl SoC pinctrl driver"
depends on ARM64
depends on ARM64 || COMPILE_TEST
select PINCTRL_MESON8_PMX
default ARCH_MESON
@ -42,7 +42,7 @@ config PINCTRL_MESON8_PMX
config PINCTRL_MESON_AXG
tristate "Meson axg Soc pinctrl driver"
depends on ARM64
depends on ARM64 || COMPILE_TEST
select PINCTRL_MESON_AXG_PMX
default ARCH_MESON
@ -51,25 +51,25 @@ config PINCTRL_MESON_AXG_PMX
config PINCTRL_MESON_G12A
tristate "Meson g12a Soc pinctrl driver"
depends on ARM64
depends on ARM64 || COMPILE_TEST
select PINCTRL_MESON_AXG_PMX
default ARCH_MESON
config PINCTRL_MESON_A1
tristate "Meson a1 Soc pinctrl driver"
depends on ARM64
depends on ARM64 || COMPILE_TEST
select PINCTRL_MESON_AXG_PMX
default ARCH_MESON
config PINCTRL_MESON_S4
tristate "Meson s4 Soc pinctrl driver"
depends on ARM64
depends on ARM64 || COMPILE_TEST
select PINCTRL_MESON_AXG_PMX
default ARCH_MESON
config PINCTRL_AMLOGIC_A4
bool "AMLOGIC pincontrol"
depends on ARM64
depends on ARM64 || COMPILE_TEST
default ARCH_MESON
help
This is the driver for the pin controller found on Amlogic SoCs.
@ -80,13 +80,13 @@ config PINCTRL_AMLOGIC_A4
config PINCTRL_AMLOGIC_C3
tristate "Amlogic C3 SoC pinctrl driver"
depends on ARM64
depends on ARM64 || COMPILE_TEST
select PINCTRL_MESON_AXG_PMX
default ARCH_MESON
config PINCTRL_AMLOGIC_T7
tristate "Amlogic T7 SoC pinctrl driver"
depends on ARM64
depends on ARM64 || COMPILE_TEST
select PINCTRL_MESON_AXG_PMX
default ARCH_MESON

View file

@ -24,6 +24,7 @@
#include <dt-bindings/pinctrl/amlogic,pinctrl.h>
#include "../core.h"
#include "../pinctrl-utils.h"
#include "../pinconf.h"
#define gpio_chip_to_bank(chip) \
@ -672,11 +673,79 @@ static void aml_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
seq_printf(s, " %s", dev_name(pcdev->dev));
}
static int aml_dt_node_to_map_pinmux(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map,
unsigned int *num_maps)
{
struct device *dev = pctldev->dev;
struct device_node *pnode;
unsigned long *configs = NULL;
unsigned int num_configs = 0;
struct property *prop;
unsigned int reserved_maps;
int reserve;
int ret;
prop = of_find_property(np, "pinmux", NULL);
if (!prop) {
dev_info(dev, "Missing pinmux property\n");
return -ENOENT;
}
pnode = of_get_parent(np);
if (!pnode) {
dev_info(dev, "Missing function node\n");
return -EINVAL;
}
reserved_maps = 0;
*map = NULL;
*num_maps = 0;
ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
&num_configs);
if (ret < 0) {
dev_err(dev, "%pOF: could not parse node property\n", np);
return ret;
}
reserve = 1;
if (num_configs)
reserve++;
ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps,
num_maps, reserve);
if (ret < 0)
goto exit;
ret = pinctrl_utils_add_map_mux(pctldev, map,
&reserved_maps, num_maps, np->name,
pnode->name);
if (ret < 0)
goto exit;
if (num_configs) {
ret = pinctrl_utils_add_map_configs(pctldev, map, &reserved_maps,
num_maps, np->name, configs,
num_configs, PIN_MAP_TYPE_CONFIGS_GROUP);
if (ret < 0)
goto exit;
}
exit:
kfree(configs);
if (ret)
pinctrl_utils_free_map(pctldev, *map, *num_maps);
return ret;
}
static const struct pinctrl_ops aml_pctrl_ops = {
.get_groups_count = aml_get_groups_count,
.get_group_name = aml_get_group_name,
.get_group_pins = aml_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pinmux,
.dt_node_to_map = aml_dt_node_to_map_pinmux,
.dt_free_map = pinconf_generic_dt_free_map,
.pin_dbg_show = aml_pin_dbg_show,
};
@ -725,8 +794,9 @@ static u32 aml_bank_pins(struct device_node *np)
if (of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
0, &of_args))
return 0;
else
return of_args.args[2];
of_node_put(of_args.np);
return of_args.args[2];
}
static int aml_bank_number(struct device_node *np)
@ -736,8 +806,9 @@ static int aml_bank_number(struct device_node *np)
if (of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
0, &of_args))
return -EINVAL;
else
return of_args.args[1] >> 8;
of_node_put(of_args.np);
return of_args.args[1] >> 8;
}
static unsigned int aml_count_pins(struct device_node *np)
@ -893,7 +964,7 @@ static const struct gpio_chip aml_gpio_template = {
.direction_input = aml_gpio_direction_input,
.direction_output = aml_gpio_direction_output,
.get_direction = aml_gpio_get_direction,
.can_sleep = false,
.can_sleep = true,
};
static void init_bank_register_bit(struct aml_pinctrl *info,

View file

@ -0,0 +1,18 @@
# SPDX-License-Identifier: GPL-2.0-only
config PINCTRL_PIC64GX
bool "pic64gx gpio2 pinctrl driver"
depends on ARCH_MICROCHIP || COMPILE_TEST
depends on OF
select GENERIC_PINCONF
select REGMAP_MMIO
help
This selects the pinctrl driver for gpio2 on pic64gx.
config PINCTRL_POLARFIRE_SOC
bool "Polarfire SoC pinctrl drivers"
depends on ARCH_MICROCHIP || COMPILE_TEST
depends on OF
select GENERIC_PINCTRL
help
This selects the pinctrl drivers for Microchip Polarfire SoC.

View file

@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_PINCTRL_PIC64GX) += pinctrl-pic64gx-gpio2.o
obj-$(CONFIG_PINCTRL_POLARFIRE_SOC) += pinctrl-mpfs-iomux0.o
obj-$(CONFIG_PINCTRL_POLARFIRE_SOC) += pinctrl-mpfs-mssio.o

View file

@ -15,10 +15,10 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "core.h"
#include "pinctrl-utils.h"
#include "pinconf.h"
#include "pinmux.h"
#include "../core.h"
#include "../pinctrl-utils.h"
#include "../pinconf.h"
#include "../pinmux.h"
#define MPFS_IOMUX0_REG 0x200

View file

@ -0,0 +1,737 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/seq_file.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "../core.h"
#include "../pinctrl-utils.h"
#include "../pinconf.h"
#include "../pinmux.h"
#define MPFS_PINCTRL_PAD_MUX_MASK GENMASK(3, 0)
#define MPFS_PINCTRL_IOCFG_MASK GENMASK(14, 0)
#define MPFS_PINCTRL_IBUFMD_MASK GENMASK(2, 0)
#define MPFS_PINCTRL_DRV_MASK GENMASK(6, 3)
#define MPFS_PINCTRL_CLAMP BIT(7)
#define MPFS_PINCTRL_ENHYST BIT(8)
#define MPFS_PINCTRL_LOCKDN BIT(9)
#define MPFS_PINCTRL_WPD BIT(10)
#define MPFS_PINCTRL_WPU BIT(11)
#define MPFS_PINCTRL_PULL_MASK GENMASK(11, 10)
#define MPFS_PINCTRL_LP_PERSIST_EN BIT(12)
#define MPFS_PINCTRL_LP_BYPASS_EN BIT(13)
#define MPFS_PINCTRL_MSSIO_BANK2_CFG_CR 0x1c4
#define MPFS_PINCTRL_MSSIO_BANK4_CFG_CR 0x1c8
#define MPFS_PINCTRL_BANK_VOLTAGE_MASK GENMASK(19, 16)
#define MPFS_PINCTRL_IOCFG01_REG 0x234
#define MPFS_PINCTRL_INTER_BANK_GAP 0x4
#define MPFS_PINCTRL_BANK2_START 14
#define MPFS_PINCTRL_LOCKDOWN (PIN_CONFIG_END + 1)
#define MPFS_PINCTRL_CLAMP_DIODE (PIN_CONFIG_END + 2)
#define MPFS_PINCTRL_IBUFMD (PIN_CONFIG_END + 3)
struct mpfs_pinctrl_mux_config {
u8 pin;
u8 function;
};
struct mpfs_pinctrl {
struct pinctrl_dev *pctrl;
struct device *dev;
struct regmap *regmap;
struct regmap *sysreg_regmap;
struct mutex mutex;
struct pinctrl_desc desc;
};
struct mpfs_pinctrl_drive_strength {
u8 ma;
u8 val;
};
struct mpfs_pinctrl_bank_voltage {
u32 uv;
u8 val;
};
static struct mpfs_pinctrl_drive_strength mpfs_pinctrl_drive_strengths[8] = {
{ .ma = 2, .val = 2 },
{ .ma = 4, .val = 3 },
{ .ma = 6, .val = 4 },
{ .ma = 8, .val = 5 },
{ .ma = 10, .val = 6 },
{ .ma = 12, .val = 7 },
{ .ma = 16, .val = 10 },
{ .ma = 20, .val = 12 },
};
static struct mpfs_pinctrl_bank_voltage mpfs_pinctrl_bank_voltages[8] = {
{ .uv = 1200000, .val = 0 },
{ .uv = 1500000, .val = 2 },
{ .uv = 1800000, .val = 4 },
{ .uv = 2500000, .val = 6 },
{ .uv = 3300000, .val = 8 },
{ .uv = 0, .val = 0x3f }, // pin unused
};
static int mpfs_pinctrl_get_drive_strength_ma(u32 drive_strength)
{
size_t num = ARRAY_SIZE(mpfs_pinctrl_drive_strengths);
for (int i = 0; i < num; i++)
if (drive_strength == mpfs_pinctrl_drive_strengths[i].val)
return mpfs_pinctrl_drive_strengths[i].ma;
return -EINVAL;
}
static int mpfs_pinctrl_get_drive_strength_val(u32 drive_strength_ma)
{
size_t num = ARRAY_SIZE(mpfs_pinctrl_drive_strengths);
if (!drive_strength_ma)
return -EINVAL;
for (int i = 0; i < num; i++)
if (drive_strength_ma <= mpfs_pinctrl_drive_strengths[i].ma)
return mpfs_pinctrl_drive_strengths[i].val;
return mpfs_pinctrl_drive_strengths[num - 1].val;
}
static int mpfs_pinctrl_get_bank_voltage_uv(u32 bank_voltage)
{
size_t num = ARRAY_SIZE(mpfs_pinctrl_bank_voltages);
for (int i = 0; i < num; i++)
if (bank_voltage == mpfs_pinctrl_bank_voltages[i].val)
return mpfs_pinctrl_bank_voltages[i].uv;
return -EINVAL;
}
static int mpfs_pinctrl_get_bank_voltage_val(u32 bank_voltage_uv)
{
size_t num = ARRAY_SIZE(mpfs_pinctrl_bank_voltages);
for (int i = 0; i < num; i++)
if (bank_voltage_uv <= mpfs_pinctrl_bank_voltages[i].uv)
return mpfs_pinctrl_bank_voltages[i].val;
return -EINVAL;
}
static u32 mpfs_pinctrl_pin_to_bank_voltage(struct mpfs_pinctrl *pctrl, unsigned int pin)
{
u32 bank_voltage, val;
if (pin < MPFS_PINCTRL_BANK2_START)
regmap_read(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK4_CFG_CR, &val);
else
regmap_read(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK2_CFG_CR, &val);
bank_voltage = FIELD_GET(MPFS_PINCTRL_BANK_VOLTAGE_MASK, val);
return mpfs_pinctrl_get_bank_voltage_uv(bank_voltage);
}
static void mpfs_pinctrl_set_bank_voltage(struct mpfs_pinctrl *pctrl, unsigned int pin,
u32 bank_voltage)
{
u32 val = FIELD_PREP(MPFS_PINCTRL_BANK_VOLTAGE_MASK, bank_voltage);
if (pin < MPFS_PINCTRL_BANK2_START)
regmap_assign_bits(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK4_CFG_CR,
MPFS_PINCTRL_BANK_VOLTAGE_MASK, val);
else
regmap_assign_bits(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK2_CFG_CR,
MPFS_PINCTRL_BANK_VOLTAGE_MASK, val);
}
static char *mpfs_pinctrl_function_names[] = {
"sd",
"emmc",
"qspi",
"spi",
"usb",
"uart",
"i2c",
"can",
"mdio",
"misc",
"reserved",
"gpio",
"fabric test",
"tied-low",
"tied-high",
"tristate"
};
static int mpfs_pinctrl_function_map(const char *function)
{
size_t num = ARRAY_SIZE(mpfs_pinctrl_function_names);
for (int i = 0; i < num; i++)
if (!strcmp(function, mpfs_pinctrl_function_names[i]))
return i;
return -EINVAL;
}
static const struct pinconf_generic_params mpfs_pinctrl_custom_bindings[] = {
{ "microchip,clamp-diode", MPFS_PINCTRL_CLAMP_DIODE, 1 },
{ "microchip,ibufmd", MPFS_PINCTRL_IBUFMD, 0x0 },
};
static int mpfs_pinctrl_pin_to_iomux_offset(unsigned int pin)
{
int offset;
switch (pin) {
case 0 ... 7:
offset = pin * 4;
break;
case 8 ... 13:
offset = (pin - 8) * 4;
break;
case 14 ... 21:
offset = (pin - 14) * 4;
break;
case 22 ... 29:
offset = (pin - 22) * 4;
break;
case 30 ... 37:
offset = (pin - 30) * 4;
break;
default:
offset = -EINVAL;
}
return offset;
}
static int mpfs_pinctrl_pin_to_iomux_reg(unsigned int pin)
{
int reg;
switch (pin) {
case 0 ... 7:
reg = 0x204;
break;
case 8 ... 13:
reg = 0x208;
break;
case 14 ... 21:
reg = 0x20c;
break;
case 22 ... 29:
reg = 0x210;
break;
case 30 ... 37:
reg = 0x214;
break;
default:
reg = -EINVAL;
}
return reg;
}
static int mpfs_pinctrl_pin_to_iocfg_reg(unsigned int pin)
{
u32 reg = MPFS_PINCTRL_IOCFG01_REG;
if (pin >= MPFS_PINCTRL_BANK2_START)
reg += MPFS_PINCTRL_INTER_BANK_GAP;
// 2 pins per 32-bit register
reg += (pin / 2) * 0x4;
return reg;
}
static int mpfs_pinctrl_pin_to_iocfg_offset(unsigned int pin)
{
return 16 * (pin % 2);
}
static void mpfs_pinctrl_dbg_show(struct pinctrl_dev *pctrl_dev, struct seq_file *seq,
unsigned int pin)
{
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
u32 func;
int reg, offset;
reg = mpfs_pinctrl_pin_to_iomux_reg(pin);
offset = mpfs_pinctrl_pin_to_iomux_offset(pin);
seq_printf(seq, "reg: %x, offset: %u ", reg, offset);
seq_printf(seq, "pin: %u ", pin);
if (reg < 0 || offset < 0)
return;
regmap_read(pctrl->regmap, reg, &func);
func = (func >> offset) & MPFS_PINCTRL_PAD_MUX_MASK;
seq_printf(seq, "func: %s (%x)\n", mpfs_pinctrl_function_names[func], func);
}
static const struct pinctrl_ops mpfs_pinctrl_ops = {
.get_groups_count = pinctrl_generic_get_group_count,
.get_group_name = pinctrl_generic_get_group_name,
.get_group_pins = pinctrl_generic_get_group_pins,
.pin_dbg_show = mpfs_pinctrl_dbg_show,
.dt_node_to_map = pinctrl_generic_pins_function_dt_node_to_map,
.dt_free_map = pinctrl_utils_free_map,
};
static int mpfs_pinctrl_set_pin_func(struct mpfs_pinctrl *pctrl, u8 pin, u8 function)
{
struct device *dev = pctrl->dev;
int reg, offset;
u32 func, mask;
reg = mpfs_pinctrl_pin_to_iomux_reg(pin);
offset = mpfs_pinctrl_pin_to_iomux_offset(pin);
func = function << offset;
mask = MPFS_PINCTRL_PAD_MUX_MASK << offset;
dev_dbg(dev, "Setting pin %u. reg: %x offset %u func %x\n", pin, reg, offset, func);
if (reg < 0 || offset < 0)
return -EINVAL;
regmap_update_bits(pctrl->regmap, reg, mask, func);
return 0;
}
static int mpfs_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev, unsigned int fsel,
unsigned int gsel)
{
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
const struct group_desc *group;
const char **functions;
group = pinctrl_generic_get_group(pctrl_dev, gsel);
if (!group)
return -EINVAL;
functions = group->data;
for (int i = 0; i < group->grp.npins; i++) {
int function;
function = mpfs_pinctrl_function_map(functions[i]);
if (function < 0) {
dev_err(pctrl->dev, "invalid function %s\n", functions[i]);
return function;
}
mpfs_pinctrl_set_pin_func(pctrl, group->grp.pins[i], function);
}
return 0;
}
static const struct pinmux_ops mpfs_pinctrl_pinmux_ops = {
.get_functions_count = pinmux_generic_get_function_count,
.get_function_name = pinmux_generic_get_function_name,
.get_function_groups = pinmux_generic_get_function_groups,
.set_mux = mpfs_pinctrl_set_mux,
};
static int mpfs_pinctrl_pinconf_get(struct pinctrl_dev *pctrl_dev, unsigned int pin,
unsigned long *config)
{
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
int param = pinconf_to_config_param(*config);
int reg = mpfs_pinctrl_pin_to_iocfg_reg(pin);
int val;
u32 arg;
u8 str;
regmap_read(pctrl->regmap, reg, &val);
val = val >> mpfs_pinctrl_pin_to_iocfg_offset(pin);
val = val & MPFS_PINCTRL_IOCFG_MASK;
switch (param) {
case PIN_CONFIG_BIAS_BUS_HOLD:
if (!(val & MPFS_PINCTRL_WPD))
return -EINVAL;
if (!(val & MPFS_PINCTRL_WPU))
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (!(val & MPFS_PINCTRL_WPD))
return -EINVAL;
if (val & MPFS_PINCTRL_WPU)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (!(val & MPFS_PINCTRL_WPU))
return -EINVAL;
if (val & MPFS_PINCTRL_WPD)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_BIAS_DISABLE:
if (val & MPFS_PINCTRL_PULL_MASK)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
str = FIELD_GET(MPFS_PINCTRL_DRV_MASK, val);
if (!str)
return -EINVAL;
arg = mpfs_pinctrl_get_drive_strength_ma(str);
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
if (!FIELD_GET(MPFS_PINCTRL_ENHYST, val))
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_PERSIST_STATE:
if (!FIELD_GET(MPFS_PINCTRL_LP_PERSIST_EN, val))
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_MODE_LOW_POWER:
if (!FIELD_GET(MPFS_PINCTRL_LP_BYPASS_EN, val))
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_POWER_SOURCE:
arg = mpfs_pinctrl_pin_to_bank_voltage(pctrl, pin);
break;
case MPFS_PINCTRL_CLAMP_DIODE:
if (!FIELD_GET(MPFS_PINCTRL_CLAMP, val))
return -EINVAL;
arg = 1;
break;
case MPFS_PINCTRL_LOCKDOWN:
/*
* Lockdown is a read-only configuration, it'll get set if the
* tamper unit triggers global lockdown and lockdown has been
* set in the MSS Configurator for the bank a pin belongs to.
*/
if (!FIELD_GET(MPFS_PINCTRL_LOCKDN, val))
return -EINVAL;
arg = 1;
break;
case MPFS_PINCTRL_IBUFMD:
arg = FIELD_GET(MPFS_PINCTRL_IBUFMD_MASK, val);
break;
default:
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int mpfs_pinctrl_pinconf_generate_config(struct mpfs_pinctrl *pctrl, unsigned int pin,
unsigned long *configs, unsigned int num_configs,
u32 *value, u32 *bank_voltage)
{
u32 val = 0;
for (int i = 0; i < num_configs; i++) {
int param, tmp;
u32 arg;
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_BUS_HOLD:
val |= MPFS_PINCTRL_PULL_MASK;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
val &= ~MPFS_PINCTRL_PULL_MASK;
val |= MPFS_PINCTRL_WPD;
break;
case PIN_CONFIG_BIAS_PULL_UP:
val &= ~MPFS_PINCTRL_PULL_MASK;
val |= MPFS_PINCTRL_WPU;
break;
case PIN_CONFIG_BIAS_DISABLE:
val &= ~MPFS_PINCTRL_PULL_MASK;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
tmp = mpfs_pinctrl_get_drive_strength_val(arg);
if (tmp < 0)
return tmp;
val |= FIELD_PREP(MPFS_PINCTRL_DRV_MASK, tmp);
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
if (!arg)
break;
val |= MPFS_PINCTRL_ENHYST;
break;
case PIN_CONFIG_PERSIST_STATE:
val |= MPFS_PINCTRL_LP_PERSIST_EN;
break;
case PIN_CONFIG_MODE_LOW_POWER:
if (arg)
val |= MPFS_PINCTRL_LP_BYPASS_EN;
break;
case PIN_CONFIG_POWER_SOURCE:
tmp = mpfs_pinctrl_get_bank_voltage_val(arg);
if (tmp < 0)
return tmp;
*bank_voltage = tmp;
break;
case MPFS_PINCTRL_CLAMP_DIODE:
val |= MPFS_PINCTRL_CLAMP;
break;
case MPFS_PINCTRL_IBUFMD:
val |= FIELD_PREP(MPFS_PINCTRL_IBUFMD_MASK, arg);
break;
default:
dev_err(pctrl->dev, "config %u not supported\n", param);
return -ENOTSUPP;
}
}
*value = val;
return 0;
}
static int mpfs_pinctrl_pin_set_config(struct mpfs_pinctrl *pctrl, unsigned int pin, u32 config)
{
int reg = mpfs_pinctrl_pin_to_iocfg_reg(pin);
int offset = mpfs_pinctrl_pin_to_iocfg_offset(pin);
u32 val, mask;
mask = MPFS_PINCTRL_IOCFG_MASK << offset;
val = config << offset;
regmap_update_bits(pctrl->regmap, reg, mask, val);
return 0;
}
static int mpfs_pinctrl_pinconf_set(struct pinctrl_dev *pctrl_dev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
u32 val, bank_voltage = 0;
int ret;
ret = mpfs_pinctrl_pinconf_generate_config(pctrl, pin, configs, num_configs, &val,
&bank_voltage);
if (ret)
return ret;
ret = mpfs_pinctrl_pin_set_config(pctrl, pin, val);
if (ret)
return ret;
if (bank_voltage)
mpfs_pinctrl_set_bank_voltage(pctrl, pin, bank_voltage);
return 0;
}
static int mpfs_pinctrl_pinconf_group_set(struct pinctrl_dev *pctrl_dev, unsigned int gsel,
unsigned long *configs, unsigned int num_configs)
{
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
const struct group_desc *group;
unsigned int pin;
u32 val, bank_voltage = 0;
int ret;
group = pinctrl_generic_get_group(pctrl_dev, gsel);
if (!group)
return -EINVAL;
/*
* Assume that the first pin in a group is representative, as the mss
* configurator doesn't allow splitting a function between two banks.
*/
pin = group->grp.pins[0];
ret = mpfs_pinctrl_pinconf_generate_config(pctrl, pin, configs, num_configs, &val,
&bank_voltage);
if (ret)
return ret;
for (int i = 0; i < group->grp.npins; i++)
mpfs_pinctrl_pin_set_config(pctrl, group->grp.pins[i], val);
if (bank_voltage)
mpfs_pinctrl_set_bank_voltage(pctrl, group->grp.pins[0], bank_voltage);
return 0;
}
static void mpfs_pinctrl_pinconf_dbg_show(struct pinctrl_dev *pctrl_dev, struct seq_file *seq,
unsigned int pin)
{
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
u32 val;
int reg, offset;
reg = mpfs_pinctrl_pin_to_iocfg_reg(pin);
offset = mpfs_pinctrl_pin_to_iocfg_offset(pin);
seq_printf(seq, "pin: %u ", pin);
seq_printf(seq, "reg: %x offset: %u ", reg, offset);
if (reg < 0 || offset < 0)
return;
regmap_read(pctrl->regmap, reg, &val);
val = (val & (MPFS_PINCTRL_IOCFG_MASK << offset)) >> offset;
seq_printf(seq, "val: %x\n", val);
}
static const struct pinconf_ops mpfs_pinctrl_pinconf_ops = {
.pin_config_get = mpfs_pinctrl_pinconf_get,
.pin_config_set = mpfs_pinctrl_pinconf_set,
.pin_config_group_set = mpfs_pinctrl_pinconf_group_set,
.pin_config_dbg_show = mpfs_pinctrl_pinconf_dbg_show,
.is_generic = true,
};
static const struct pinctrl_pin_desc mpfs_pinctrl_pins[] = {
PINCTRL_PIN(0, "bank 4 0"),
PINCTRL_PIN(1, "bank 4 1"),
PINCTRL_PIN(2, "bank 4 2"),
PINCTRL_PIN(3, "bank 4 3"),
PINCTRL_PIN(4, "bank 4 4"),
PINCTRL_PIN(5, "bank 4 5"),
PINCTRL_PIN(6, "bank 4 6"),
PINCTRL_PIN(7, "bank 4 7"),
PINCTRL_PIN(8, "bank 4 8"),
PINCTRL_PIN(9, "bank 4 9"),
PINCTRL_PIN(10, "bank 4 10"),
PINCTRL_PIN(11, "bank 4 11"),
PINCTRL_PIN(12, "bank 4 12"),
PINCTRL_PIN(13, "bank 4 13"),
PINCTRL_PIN(14, "bank 2 0"),
PINCTRL_PIN(15, "bank 2 1"),
PINCTRL_PIN(16, "bank 2 2"),
PINCTRL_PIN(17, "bank 2 3"),
PINCTRL_PIN(18, "bank 2 4"),
PINCTRL_PIN(19, "bank 2 5"),
PINCTRL_PIN(20, "bank 2 6"),
PINCTRL_PIN(21, "bank 2 7"),
PINCTRL_PIN(22, "bank 2 8"),
PINCTRL_PIN(23, "bank 2 9"),
PINCTRL_PIN(24, "bank 2 10"),
PINCTRL_PIN(25, "bank 2 11"),
PINCTRL_PIN(26, "bank 2 12"),
PINCTRL_PIN(27, "bank 2 13"),
PINCTRL_PIN(28, "bank 2 14"),
PINCTRL_PIN(29, "bank 2 15"),
PINCTRL_PIN(30, "bank 2 16"),
PINCTRL_PIN(31, "bank 2 17"),
PINCTRL_PIN(32, "bank 2 18"),
PINCTRL_PIN(33, "bank 2 19"),
PINCTRL_PIN(34, "bank 2 20"),
PINCTRL_PIN(35, "bank 2 21"),
PINCTRL_PIN(36, "bank 2 22"),
PINCTRL_PIN(37, "bank 2 23"),
};
static int mpfs_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mpfs_pinctrl *pctrl;
int ret;
pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
return -ENOMEM;
pctrl->regmap = device_node_to_regmap(pdev->dev.parent->of_node);
if (IS_ERR(pctrl->regmap))
dev_err_probe(dev, PTR_ERR(pctrl->regmap), "Failed to find syscon regmap\n");
pctrl->sysreg_regmap = syscon_regmap_lookup_by_compatible("microchip,mpfs-sysreg-scb");
if (IS_ERR(pctrl->sysreg_regmap))
return PTR_ERR(pctrl->sysreg_regmap);
pctrl->desc.name = dev_name(dev);
pctrl->desc.pins = mpfs_pinctrl_pins;
pctrl->desc.npins = ARRAY_SIZE(mpfs_pinctrl_pins);
pctrl->desc.pctlops = &mpfs_pinctrl_ops;
pctrl->desc.pmxops = &mpfs_pinctrl_pinmux_ops;
pctrl->desc.confops = &mpfs_pinctrl_pinconf_ops;
pctrl->desc.owner = THIS_MODULE;
pctrl->desc.num_custom_params = ARRAY_SIZE(mpfs_pinctrl_custom_bindings);
pctrl->desc.custom_params = mpfs_pinctrl_custom_bindings;
pctrl->dev = dev;
ret = devm_mutex_init(dev, &pctrl->mutex);
if (ret)
return ret;
platform_set_drvdata(pdev, pctrl);
pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl);
if (IS_ERR(pctrl->pctrl))
return PTR_ERR(pctrl->pctrl);
return 0;
}
static const struct of_device_id mpfs_pinctrl_of_match[] = {
{ .compatible = "microchip,mpfs-pinctrl-mssio" },
{ }
};
MODULE_DEVICE_TABLE(of, mpfs_pinctrl_of_match);
static struct platform_driver mpfs_pinctrl_driver = {
.driver = {
.name = "mpfs-pinctrl",
.of_match_table = mpfs_pinctrl_of_match,
},
.probe = mpfs_pinctrl_probe,
};
module_platform_driver(mpfs_pinctrl_driver);
MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
MODULE_DESCRIPTION("Polarfire SoC mssio pinctrl driver");
MODULE_LICENSE("GPL");

View file

@ -14,7 +14,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "pinctrl-utils.h"
#include "../pinctrl-utils.h"
#define PIC64GX_PINMUX_REG 0x0

View file

@ -385,75 +385,6 @@ out:
}
EXPORT_SYMBOL_GPL(pinconf_generic_parse_dt_config);
int pinconf_generic_dt_node_to_map_pinmux(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map,
unsigned int *num_maps)
{
struct device *dev = pctldev->dev;
struct device_node *pnode;
unsigned long *configs = NULL;
unsigned int num_configs = 0;
struct property *prop;
unsigned int reserved_maps;
int reserve;
int ret;
prop = of_find_property(np, "pinmux", NULL);
if (!prop) {
dev_info(dev, "Missing pinmux property\n");
return -ENOENT;
}
pnode = of_get_parent(np);
if (!pnode) {
dev_info(dev, "Missing function node\n");
return -EINVAL;
}
reserved_maps = 0;
*map = NULL;
*num_maps = 0;
ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
&num_configs);
if (ret < 0) {
dev_err(dev, "%pOF: could not parse node property\n", np);
return ret;
}
reserve = 1;
if (num_configs)
reserve++;
ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps,
num_maps, reserve);
if (ret < 0)
goto exit;
ret = pinctrl_utils_add_map_mux(pctldev, map,
&reserved_maps, num_maps, np->name,
pnode->name);
if (ret < 0)
goto exit;
if (num_configs) {
ret = pinctrl_utils_add_map_configs(pctldev, map, &reserved_maps,
num_maps, np->name, configs,
num_configs, PIN_MAP_TYPE_CONFIGS_GROUP);
if (ret < 0)
goto exit;
}
exit:
kfree(configs);
if (ret)
pinctrl_utils_free_map(pctldev, *map, *num_maps);
return ret;
}
EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map_pinmux);
int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np, struct pinctrl_map **map,
unsigned int *reserved_maps, unsigned int *num_maps,

View file

@ -160,3 +160,19 @@ pinconf_generic_parse_dt_pinmux(struct device_node *np, struct device *dev,
return -ENOTSUPP;
}
#endif
#if defined(CONFIG_GENERIC_PINCTRL) && defined (CONFIG_OF)
int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **maps,
unsigned int *num_maps);
#else
static inline int
pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **maps,
unsigned int *num_maps)
{
return -ENOTSUPP;
}
#endif

View file

@ -21,11 +21,9 @@
#include <linux/gpio/driver.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/bitops.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>

View file

@ -102,9 +102,9 @@ static u32 apple_gpio_get_reg(struct apple_gpio_pinctrl *pctl,
static int apple_gpio_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *node,
struct pinctrl_map **map,
unsigned *num_maps)
unsigned int *num_maps)
{
unsigned reserved_maps;
unsigned int reserved_maps;
struct apple_gpio_pinctrl *pctl;
u32 pinfunc, pin, func;
int num_pins, i, ret;
@ -170,8 +170,15 @@ static const struct pinctrl_ops apple_gpio_pinctrl_ops = {
/* Pin multiplexer functions */
static int apple_gpio_pinmux_set(struct pinctrl_dev *pctldev, unsigned func,
unsigned group)
static bool apple_gpio_pinmux_func_is_gpio(struct pinctrl_dev *pctldev,
unsigned int selector)
{
/* Function selector 0 is always the GPIO mode */
return (selector == 0);
}
static int apple_gpio_pinmux_set(struct pinctrl_dev *pctldev, unsigned int func,
unsigned int group)
{
struct apple_gpio_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
@ -186,6 +193,7 @@ static const struct pinmux_ops apple_gpio_pinmux_ops = {
.get_functions_count = pinmux_generic_get_function_count,
.get_function_name = pinmux_generic_get_function_name,
.get_function_groups = pinmux_generic_get_function_groups,
.function_is_gpio = apple_gpio_pinmux_func_is_gpio,
.set_mux = apple_gpio_pinmux_set,
.strict = true,
};
@ -202,7 +210,7 @@ static int apple_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
return GPIO_LINE_DIRECTION_IN;
}
static int apple_gpio_get(struct gpio_chip *chip, unsigned offset)
static int apple_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip);
unsigned int reg = apple_gpio_get_reg(pctl, offset);

View file

@ -1053,6 +1053,12 @@ static const struct atmel_pioctrl_data atmel_sama5d2_pioctrl_data = {
.last_bank_count = ATMEL_PIO_NPINS_PER_BANK,
};
static const struct atmel_pioctrl_data microchip_sama7d65_pioctrl_data = {
.nbanks = 5,
.last_bank_count = 14, /* sama7d65 has only PE0 to PE13 */
.slew_rate_support = 1,
};
static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = {
.nbanks = 5,
.last_bank_count = 8, /* sama7g5 has only PE0 to PE7 */
@ -1063,6 +1069,9 @@ static const struct of_device_id atmel_pctrl_of_match[] = {
{
.compatible = "atmel,sama5d2-pinctrl",
.data = &atmel_sama5d2_pioctrl_data,
}, {
.compatible = "microchip,sama7d65-pinctrl",
.data = &microchip_sama7d65_pioctrl_data,
}, {
.compatible = "microchip,sama7g5-pinctrl",
.data = &microchip_sama7g5_pioctrl_data,

View file

@ -291,14 +291,14 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned int mask, val;
int i, rc;
mutex_lock(&awi->i2c_lock);
guard(mutex)(&awi->i2c_lock);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
rc = aw9523_pcfg_param_to_reg(param, pin, &reg);
if (rc)
goto end;
return rc;
switch (param) {
case PIN_CONFIG_LEVEL:
@ -307,7 +307,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
AW9523_REG_CONF_STATE(pin),
BIT(regbit), 0);
if (rc)
goto end;
return rc;
/* Then, fall through to config output level */
fallthrough;
@ -323,10 +323,9 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
/* Open-Drain is supported only on port 0 */
if (pin >= AW9523_PINS_PER_PORT) {
rc = -ENOTSUPP;
goto end;
}
if (pin >= AW9523_PINS_PER_PORT)
return -ENOTSUPP;
mask = AW9523_GCR_GPOMD_MASK;
val = 0;
break;
@ -341,17 +340,15 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
val = AW9523_GCR_GPOMD_MASK;
break;
default:
rc = -ENOTSUPP;
goto end;
return -ENOTSUPP;
}
rc = regmap_update_bits(awi->regmap, reg, mask, val);
if (rc)
goto end;
return rc;
}
end:
mutex_unlock(&awi->i2c_lock);
return rc;
return 0;
}
static const struct pinconf_ops aw9523_pinconf_ops = {
@ -599,14 +596,14 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
u8 m, state = 0;
int ret;
mutex_lock(&awi->i2c_lock);
guard(mutex)(&awi->i2c_lock);
/* Port 0 (gpio 0-7) */
m = *mask;
if (m) {
ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
if (ret)
goto out;
return ret;
}
*bits = state;
@ -616,13 +613,12 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
&state, m);
if (ret)
goto out;
return ret;
*bits |= (state << 8);
}
out:
mutex_unlock(&awi->i2c_lock);
return ret;
return 0;
}
static int aw9523_gpio_set_multiple(struct gpio_chip *chip,
@ -632,30 +628,28 @@ static int aw9523_gpio_set_multiple(struct gpio_chip *chip,
struct aw9523 *awi = gpiochip_get_data(chip);
u8 mask_lo, mask_hi, bits_lo, bits_hi;
unsigned int reg;
int ret = 0;
int ret;
mask_lo = *mask;
mask_hi = *mask >> 8;
bits_lo = *bits;
bits_hi = *bits >> 8;
mutex_lock(&awi->i2c_lock);
guard(mutex)(&awi->i2c_lock);
if (mask_hi) {
reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
if (ret)
goto out;
return ret;
}
if (mask_lo) {
reg = AW9523_REG_OUT_STATE(0);
ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
if (ret)
goto out;
return ret;
}
out:
mutex_unlock(&awi->i2c_lock);
return ret;
return 0;
}
static int aw9523_gpio_set(struct gpio_chip *chip, unsigned int offset,
@ -695,16 +689,15 @@ static int aw9523_direction_output(struct gpio_chip *chip,
u8 regbit = offset % AW9523_PINS_PER_PORT;
int ret;
mutex_lock(&awi->i2c_lock);
guard(mutex)(&awi->i2c_lock);
ret = regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
BIT(regbit), value ? BIT(regbit) : 0);
if (ret)
goto end;
return ret;
ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
BIT(regbit), 0);
end:
mutex_unlock(&awi->i2c_lock);
return ret;
}

View file

@ -846,6 +846,7 @@ static int pinbank_init(struct device_node *np,
bank->pin_base = spec.args[1];
bank->nr_pins = spec.args[2];
of_node_put(spec.np);
bank->aval_pinmap = readl(bank->membase + REG_AVAIL);
bank->id = id;

View file

@ -0,0 +1,189 @@
// SPDX-License-Identifier: GPL-2.0-only
#define pr_fmt(fmt) "generic pinconfig core: " fmt
#include <linux/array_size.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include "core.h"
#include "pinconf.h"
#include "pinctrl-utils.h"
#include "pinmux.h"
static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *parent,
struct device_node *np,
struct pinctrl_map **maps,
unsigned int *num_maps,
unsigned int *num_reserved_maps,
const char **group_names,
unsigned int ngroups)
{
struct device *dev = pctldev->dev;
const char **functions;
const char *group_name;
unsigned long *configs;
unsigned int num_configs, pin, *pins;
int npins, ret, reserve = 1;
npins = of_property_count_u32_elems(np, "pins");
if (npins < 1) {
dev_err(dev, "invalid pinctrl group %pOFn.%pOFn %d\n",
parent, np, npins);
return npins;
}
group_name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", parent, np);
if (!group_name)
return -ENOMEM;
group_names[ngroups] = group_name;
pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
if (!pins)
return -ENOMEM;
functions = devm_kcalloc(dev, npins, sizeof(*functions), GFP_KERNEL);
if (!functions)
return -ENOMEM;
for (int i = 0; i < npins; i++) {
ret = of_property_read_u32_index(np, "pins", i, &pin);
if (ret)
return ret;
pins[i] = pin;
ret = of_property_read_string(np, "function", &functions[i]);
if (ret)
return ret;
}
ret = pinctrl_utils_reserve_map(pctldev, maps, num_reserved_maps, num_maps, reserve);
if (ret)
return ret;
ret = pinctrl_utils_add_map_mux(pctldev, maps, num_reserved_maps, num_maps, group_name,
parent->name);
if (ret < 0)
return ret;
ret = pinctrl_generic_add_group(pctldev, group_name, pins, npins, functions);
if (ret < 0)
return dev_err_probe(dev, ret, "failed to add group %s: %d\n",
group_name, ret);
ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs);
if (ret)
return dev_err_probe(dev, ret, "failed to parse pin config of group %s\n",
group_name);
if (num_configs == 0)
return 0;
ret = pinctrl_utils_reserve_map(pctldev, maps, num_reserved_maps, num_maps, reserve);
if (ret)
return ret;
ret = pinctrl_utils_add_map_configs(pctldev, maps, num_reserved_maps, num_maps, group_name,
configs,
num_configs, PIN_MAP_TYPE_CONFIGS_GROUP);
kfree(configs);
if (ret)
return ret;
return 0;
};
/*
* For platforms that do not define groups or functions in the driver, but
* instead use the devicetree to describe them. This function will, unlike
* pinconf_generic_dt_node_to_map() etc which rely on driver defined groups
* and functions, create them in addition to parsing pinconf properties and
* adding mappings.
*/
int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **maps,
unsigned int *num_maps)
{
struct device *dev = pctldev->dev;
struct device_node *child_np;
const char **group_names;
unsigned int num_reserved_maps = 0;
int ngroups = 0;
int ret;
*maps = NULL;
*num_maps = 0;
/*
* Check if this is actually the pins node, or a parent containing
* multiple pins nodes.
*/
if (!of_property_present(np, "pins"))
goto parent;
group_names = devm_kcalloc(dev, 1, sizeof(*group_names), GFP_KERNEL);
if (!group_names)
return -ENOMEM;
ret = pinctrl_generic_pins_function_dt_subnode_to_map(pctldev, np, np,
maps, num_maps,
&num_reserved_maps,
group_names,
ngroups);
if (ret) {
pinctrl_utils_free_map(pctldev, *maps, *num_maps);
return dev_err_probe(dev, ret, "error figuring out mappings for %s\n", np->name);
}
ret = pinmux_generic_add_function(pctldev, np->name, group_names, 1, NULL);
if (ret < 0) {
pinctrl_utils_free_map(pctldev, *maps, *num_maps);
return dev_err_probe(dev, ret, "error adding function %s\n", np->name);
}
return 0;
parent:
for_each_available_child_of_node(np, child_np)
ngroups += 1;
group_names = devm_kcalloc(dev, ngroups, sizeof(*group_names), GFP_KERNEL);
if (!group_names)
return -ENOMEM;
ngroups = 0;
for_each_available_child_of_node_scoped(np, child_np) {
ret = pinctrl_generic_pins_function_dt_subnode_to_map(pctldev, np, child_np,
maps, num_maps,
&num_reserved_maps,
group_names,
ngroups);
if (ret) {
pinctrl_utils_free_map(pctldev, *maps, *num_maps);
return dev_err_probe(dev, ret, "error figuring out mappings for %s\n",
np->name);
}
ngroups++;
}
ret = pinmux_generic_add_function(pctldev, np->name, group_names, ngroups, NULL);
if (ret < 0) {
pinctrl_utils_free_map(pctldev, *maps, *num_maps);
return dev_err_probe(dev, ret, "error adding function %s\n", np->name);
}
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_generic_pins_function_dt_node_to_map);

View file

@ -65,6 +65,7 @@ struct k230_pmx_func {
};
struct k230_pinctrl {
struct device *dev;
struct pinctrl_desc pctl;
struct pinctrl_dev *pctl_dev;
struct regmap *regmap_base;
@ -470,7 +471,7 @@ static int k230_pinctrl_parse_groups(struct device_node *np,
struct k230_pinctrl *info,
unsigned int index)
{
struct device *dev = info->pctl_dev->dev;
struct device *dev = info->dev;
const __be32 *list;
int size, i, ret;
@ -511,7 +512,7 @@ static int k230_pinctrl_parse_functions(struct device_node *np,
struct k230_pinctrl *info,
unsigned int index)
{
struct device *dev = info->pctl_dev->dev;
struct device *dev = info->dev;
struct k230_pmx_func *func;
struct k230_pin_group *grp;
static unsigned int idx, i;
@ -596,6 +597,8 @@ static int k230_pinctrl_probe(struct platform_device *pdev)
if (!info)
return -ENOMEM;
info->dev = dev;
pctl = &info->pctl;
pctl->name = "k230-pinctrl";

View file

@ -264,19 +264,17 @@ static int sgpio_single_shot(struct sgpio_priv *priv)
* setting.
* After the manual burst, reenable the auto repeat mode again.
*/
mutex_lock(&priv->poll_lock);
guard(mutex)(&priv->poll_lock);
ret = regmap_update_bits(priv->regs, addr, single_shot | auto_repeat,
single_shot);
if (ret)
goto out;
return ret;
ret = regmap_read_poll_timeout(priv->regs, addr, ctrl,
!(ctrl & single_shot), 100, 60000);
/* reenable auto repeat mode even if there was an error */
ret2 = regmap_update_bits(priv->regs, addr, auto_repeat, auto_repeat);
out:
mutex_unlock(&priv->poll_lock);
return ret ?: ret2;
}

View file

@ -97,6 +97,8 @@ enum {
FUNC_FC_SHRD20,
FUNC_FUSA,
FUNC_GPIO,
FUNC_I2C,
FUNC_I2C_Sa,
FUNC_IB_TRG_a,
FUNC_IB_TRG_b,
FUNC_IB_TRG_c,
@ -112,9 +114,11 @@ enum {
FUNC_IRQ1,
FUNC_IRQ1_IN,
FUNC_IRQ1_OUT,
FUNC_IRQ2,
FUNC_IRQ3,
FUNC_IRQ4,
FUNC_EXT_IRQ,
FUNC_MACLED,
FUNC_MIIM,
FUNC_MIIM_a,
FUNC_MIIM_b,
@ -126,6 +130,7 @@ enum {
FUNC_OB_TRG_a,
FUNC_OB_TRG_b,
FUNC_PHY_LED,
FUNC_PHY_DBG,
FUNC_PCI_WAKE,
FUNC_MD,
FUNC_PCIE_PERST,
@ -156,10 +161,12 @@ enum {
FUNC_SG0,
FUNC_SG1,
FUNC_SG2,
FUNC_SPI,
FUNC_SGPIO_a,
FUNC_SGPIO_b,
FUNC_SI,
FUNC_SI2,
FUNC_SI_Sa,
FUNC_SYNCE,
FUNC_TACHO,
FUNC_TACHO_a,
@ -188,6 +195,7 @@ enum {
FUNC_EMMC_SD,
FUNC_REF_CLK,
FUNC_RCVRD_CLK,
FUNC_RGMII,
FUNC_MAX
};
@ -237,6 +245,8 @@ static const char *const ocelot_function_names[] = {
[FUNC_FC_SHRD20] = "fc_shrd20",
[FUNC_FUSA] = "fusa",
[FUNC_GPIO] = "gpio",
[FUNC_I2C] = "i2c",
[FUNC_I2C_Sa] = "i2c_slave_a",
[FUNC_IB_TRG_a] = "ib_trig_a",
[FUNC_IB_TRG_b] = "ib_trig_b",
[FUNC_IB_TRG_c] = "ib_trig_c",
@ -252,9 +262,11 @@ static const char *const ocelot_function_names[] = {
[FUNC_IRQ1] = "irq1",
[FUNC_IRQ1_IN] = "irq1_in",
[FUNC_IRQ1_OUT] = "irq1_out",
[FUNC_IRQ2] = "irq2",
[FUNC_IRQ3] = "irq3",
[FUNC_IRQ4] = "irq4",
[FUNC_EXT_IRQ] = "ext_irq",
[FUNC_MACLED] = "mac_led",
[FUNC_MIIM] = "miim",
[FUNC_MIIM_a] = "miim_a",
[FUNC_MIIM_b] = "miim_b",
@ -263,6 +275,7 @@ static const char *const ocelot_function_names[] = {
[FUNC_MIIM_Sb] = "miim_slave_b",
[FUNC_MIIM_IRQ] = "miim_irq",
[FUNC_PHY_LED] = "phy_led",
[FUNC_PHY_DBG] = "phy_dbg",
[FUNC_PCI_WAKE] = "pci_wake",
[FUNC_PCIE_PERST] = "pcie_perst",
[FUNC_MD] = "md",
@ -300,6 +313,8 @@ static const char *const ocelot_function_names[] = {
[FUNC_SGPIO_b] = "sgpio_b",
[FUNC_SI] = "si",
[FUNC_SI2] = "si2",
[FUNC_SI_Sa] = "si_slave_a",
[FUNC_SPI] = "spi",
[FUNC_SYNCE] = "synce",
[FUNC_TACHO] = "tacho",
[FUNC_TACHO_a] = "tacho_a",
@ -328,6 +343,7 @@ static const char *const ocelot_function_names[] = {
[FUNC_EMMC_SD] = "emmc_sd",
[FUNC_REF_CLK] = "ref_clk",
[FUNC_RCVRD_CLK] = "rcvrd_clk",
[FUNC_RGMII] = "rgmii",
};
struct ocelot_pmx_func {
@ -358,12 +374,14 @@ struct ocelot_pinctrl {
const struct ocelot_pincfg_data *pincfg_data;
struct ocelot_pmx_func func[FUNC_MAX];
u8 stride;
u8 altm_stride;
struct workqueue_struct *wq;
};
struct ocelot_match_data {
struct pinctrl_desc desc;
struct ocelot_pincfg_data pincfg_data;
unsigned int n_alt_modes;
};
struct ocelot_irq_work {
@ -1321,6 +1339,132 @@ static const struct pinctrl_pin_desc lan969x_pins[] = {
LAN969X_PIN(66),
};
#define LAN9645X_P(p, f0, f1, f2, f3, f4, f5, f6, f7) \
static struct ocelot_pin_caps lan9645x_pin_##p = { \
.pin = p, \
.functions = { \
FUNC_##f0, FUNC_##f1, FUNC_##f2, \
FUNC_##f3 \
}, \
.a_functions = { \
FUNC_##f4, FUNC_##f5, FUNC_##f6, \
FUNC_##f7 \
}, \
}
/* Pin FUNC0 FUNC1 FUNC2 FUNC3 FUNC4 FUNC5 FUNC6 FUNC7 */
LAN9645X_P(0, GPIO, SPI, SI_Sa, I2C_Sa, MIIM_Sa, UART, MIIM, PHY_DBG);
LAN9645X_P(1, GPIO, SPI, SI_Sa, I2C_Sa, MIIM_Sa, UART, MIIM, PHY_DBG);
LAN9645X_P(2, GPIO, SPI, SI_Sa, I2C, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(3, GPIO, SPI, SI_Sa, I2C, MIIM_Sa, NONE, NONE, PHY_DBG);
LAN9645X_P(4, GPIO, RGMII, TWI_SCL_M, I2C, NONE, NONE, SI_Sa, PHY_DBG);
LAN9645X_P(5, GPIO, RGMII, TWI_SCL_M, I2C, NONE, NONE, SI_Sa, PHY_DBG);
LAN9645X_P(6, GPIO, RGMII, TWI_SCL_M, NONE, NONE, NONE, SI_Sa, PHY_DBG);
LAN9645X_P(7, GPIO, RGMII, TWI_SCL_M, SFP, SGPIO_a, MIIM, SI_Sa, PHY_DBG);
LAN9645X_P(8, GPIO, RGMII, TWI_SCL_M, SFP, SGPIO_a, MIIM, NONE, PHY_DBG);
LAN9645X_P(9, GPIO, RGMII, TWI_SCL_M, RECO_CLK, SGPIO_a, IRQ1, UART, PHY_DBG);
LAN9645X_P(10, GPIO, RGMII, TWI_SCL_M, RECO_CLK, SGPIO_a, IRQ2, UART, PHY_DBG);
LAN9645X_P(11, GPIO, RGMII, TWI_SCL_M, MIIM, NONE, IRQ3, NONE, PHY_DBG);
LAN9645X_P(12, GPIO, RGMII, TWI_SCL_M, MIIM, PTP0, NONE, NONE, PHY_DBG);
LAN9645X_P(13, GPIO, RGMII, TWI_SCL_M, CLKMON, PTP1, MACLED, NONE, PHY_DBG);
LAN9645X_P(14, GPIO, RGMII, TWI_SCL_M, CLKMON, PTP2, MACLED, NONE, PHY_DBG);
LAN9645X_P(15, GPIO, RGMII, TWI_SCL_M, CLKMON, PTP3, NONE, NONE, PHY_DBG);
LAN9645X_P(16, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(17, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(18, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(19, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(20, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(21, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(22, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(23, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(24, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(25, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(26, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(27, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
LAN9645X_P(28, GPIO, RECO_CLK, MIIM, NONE, NONE, NONE, NONE, R);
LAN9645X_P(29, GPIO, RECO_CLK, MIIM, NONE, NONE, NONE, NONE, R);
LAN9645X_P(30, GPIO, PTP0, I2C, UART, NONE, NONE, NONE, R);
LAN9645X_P(31, GPIO, PTP1, TWI_SCL_M, UART, NONE, NONE, NONE, R);
LAN9645X_P(32, GPIO, PTP2, TWI_SCL_M, NONE, NONE, NONE, NONE, R);
LAN9645X_P(33, GPIO, PTP3, IRQ0, NONE, NONE, NONE, NONE, R);
LAN9645X_P(34, GPIO, RECO_CLK, PHY_LED, PHY_LED, NONE, NONE, NONE, R);
LAN9645X_P(35, GPIO, RECO_CLK, PHY_LED, PHY_LED, NONE, MACLED, NONE, R);
LAN9645X_P(36, GPIO, PTP0, PHY_LED, PHY_LED, NONE, MACLED, NONE, R);
LAN9645X_P(37, GPIO, PTP1, PHY_LED, PHY_LED, NONE, MACLED, NONE, R);
LAN9645X_P(38, GPIO, NONE, PHY_LED, PHY_LED, NONE, MACLED, NONE, R);
LAN9645X_P(39, GPIO, UART, PHY_LED, NONE, NONE, MACLED, NONE, R);
LAN9645X_P(40, GPIO, SPI, PHY_LED, SGPIO_a, NONE, MACLED, NONE, R);
LAN9645X_P(41, GPIO, SPI, PHY_LED, SGPIO_a, IRQ1, MACLED, NONE, R);
LAN9645X_P(42, GPIO, SPI, PHY_LED, SGPIO_a, IRQ2, MACLED, SFP, R);
LAN9645X_P(43, GPIO, SPI, PHY_LED, SGPIO_a, IRQ3, MACLED, SFP, R);
LAN9645X_P(44, GPIO, MIIM, I2C, NONE, NONE, NONE, NONE, R);
LAN9645X_P(45, GPIO, MIIM, I2C, NONE, NONE, NONE, NONE, R);
LAN9645X_P(46, GPIO, NONE, PHY_LED, NONE, NONE, NONE, NONE, R);
LAN9645X_P(47, GPIO, NONE, PHY_LED, NONE, NONE, NONE, NONE, R);
LAN9645X_P(48, GPIO, MIIM_Sa, PHY_LED, NONE, NONE, NONE, NONE, R);
LAN9645X_P(49, GPIO, MIIM_Sa, PHY_LED, I2C_Sa, NONE, NONE, NONE, R);
LAN9645X_P(50, GPIO, MIIM_Sa, PHY_LED, I2C_Sa, NONE, NONE, NONE, R);
#define LAN9645X_PIN(n) { \
.number = n, \
.name = "GPIO_"#n, \
.drv_data = &lan9645x_pin_##n \
}
static const struct pinctrl_pin_desc lan9645x_pins[] = {
LAN9645X_PIN(0),
LAN9645X_PIN(1),
LAN9645X_PIN(2),
LAN9645X_PIN(3),
LAN9645X_PIN(4),
LAN9645X_PIN(5),
LAN9645X_PIN(6),
LAN9645X_PIN(7),
LAN9645X_PIN(8),
LAN9645X_PIN(9),
LAN9645X_PIN(10),
LAN9645X_PIN(11),
LAN9645X_PIN(12),
LAN9645X_PIN(13),
LAN9645X_PIN(14),
LAN9645X_PIN(15),
LAN9645X_PIN(16),
LAN9645X_PIN(17),
LAN9645X_PIN(18),
LAN9645X_PIN(19),
LAN9645X_PIN(20),
LAN9645X_PIN(21),
LAN9645X_PIN(22),
LAN9645X_PIN(23),
LAN9645X_PIN(24),
LAN9645X_PIN(25),
LAN9645X_PIN(26),
LAN9645X_PIN(27),
LAN9645X_PIN(28),
LAN9645X_PIN(29),
LAN9645X_PIN(30),
LAN9645X_PIN(31),
LAN9645X_PIN(32),
LAN9645X_PIN(33),
LAN9645X_PIN(34),
LAN9645X_PIN(35),
LAN9645X_PIN(36),
LAN9645X_PIN(37),
LAN9645X_PIN(38),
LAN9645X_PIN(39),
LAN9645X_PIN(40),
LAN9645X_PIN(41),
LAN9645X_PIN(42),
LAN9645X_PIN(43),
LAN9645X_PIN(44),
LAN9645X_PIN(45),
LAN9645X_PIN(46),
LAN9645X_PIN(47),
LAN9645X_PIN(48),
LAN9645X_PIN(49),
LAN9645X_PIN(50),
};
static int ocelot_get_functions_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(ocelot_function_names);
@ -1362,7 +1506,7 @@ static int ocelot_pin_function_idx(struct ocelot_pinctrl *info,
return -1;
}
#define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32))))
#define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->altm_stride * ((p) / 32))))
static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned int group)
@ -1469,6 +1613,13 @@ static int lan966x_gpio_request_enable(struct pinctrl_dev *pctldev,
return 0;
}
static int lan9645x_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
return 0;
}
static const struct pinmux_ops ocelot_pmx_ops = {
.get_functions_count = ocelot_get_functions_count,
.get_function_name = ocelot_get_function_name,
@ -1487,6 +1638,15 @@ static const struct pinmux_ops lan966x_pmx_ops = {
.gpio_request_enable = lan966x_gpio_request_enable,
};
static const struct pinmux_ops lan9645x_pmx_ops = {
.get_functions_count = ocelot_get_functions_count,
.get_function_name = ocelot_get_function_name,
.get_function_groups = ocelot_get_function_groups,
.set_mux = lan966x_pinmux_set_mux,
.gpio_set_direction = ocelot_gpio_set_direction,
.gpio_request_enable = lan9645x_gpio_request_enable,
};
static int ocelot_pctl_get_groups_count(struct pinctrl_dev *pctldev)
{
struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
@ -1884,6 +2044,24 @@ static const struct ocelot_match_data lan969x_desc = {
},
};
static struct ocelot_match_data lan9645xf_desc = {
.desc = {
.name = "lan9645xf-pinctrl",
.pins = lan9645x_pins,
.npins = ARRAY_SIZE(lan9645x_pins),
.pctlops = &ocelot_pctl_ops,
.pmxops = &lan9645x_pmx_ops,
.confops = &ocelot_confops,
.owner = THIS_MODULE,
},
.pincfg_data = {
.pd_bit = BIT(3),
.pu_bit = BIT(2),
.drive_bits = GENMASK(1, 0),
},
.n_alt_modes = 7,
};
static int ocelot_create_group_func_map(struct device *dev,
struct ocelot_pinctrl *info)
{
@ -2218,6 +2396,7 @@ static const struct of_device_id ocelot_pinctrl_of_match[] = {
{ .compatible = "microchip,sparx5-pinctrl", .data = &sparx5_desc },
{ .compatible = "microchip,lan966x-pinctrl", .data = &lan966x_desc },
{ .compatible = "microchip,lan9691-pinctrl", .data = &lan969x_desc },
{ .compatible = "microchip,lan96455f-pinctrl", .data = &lan9645xf_desc },
{},
};
MODULE_DEVICE_TABLE(of, ocelot_pinctrl_of_match);
@ -2294,6 +2473,9 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
reset_control_reset(reset);
info->stride = 1 + (info->desc->npins - 1) / 32;
info->altm_stride = info->stride;
if (data->n_alt_modes)
info->altm_stride = fls(data->n_alt_modes);
regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4;

View file

@ -3639,17 +3639,16 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
* The lock makes sure that either gpio-probe has completed
* or the gpio driver hasn't probed yet.
*/
mutex_lock(&bank->deferred_lock);
if (!gpio || !gpio->direction_output) {
rc = rockchip_pinconf_defer_pin(bank, pin - bank->pin_base, param,
arg);
mutex_unlock(&bank->deferred_lock);
if (rc)
return rc;
break;
scoped_guard(mutex, &bank->deferred_lock) {
if (!gpio || !gpio->direction_output) {
rc = rockchip_pinconf_defer_pin(bank,
pin - bank->pin_base,
param, arg);
if (rc)
return rc;
break;
}
}
mutex_unlock(&bank->deferred_lock);
}
switch (param) {

View file

@ -504,8 +504,9 @@ static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
}
static const char * const scmi_pinctrl_blocklist[] = {
"fsl,imx95",
"fsl,imx94",
"fsl,imx95",
"fsl,imx952",
NULL
};

View file

@ -1359,6 +1359,7 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
}
range = devm_kzalloc(pcs->dev, sizeof(*range), GFP_KERNEL);
if (!range) {
of_node_put(gpiospec.np);
ret = -ENOMEM;
break;
}
@ -1368,6 +1369,7 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
mutex_lock(&pcs->mutex);
list_add_tail(&range->node, &pcs->gpiofuncs);
mutex_unlock(&pcs->mutex);
of_node_put(gpiospec.np);
}
return ret;
}

View file

@ -987,6 +987,7 @@ static int st_pinconf_get(struct pinctrl_dev *pctldev,
static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin_id)
__must_hold(&pctldev->mutex)
{
struct st_pio_control *pc;
unsigned long config;

View file

@ -607,7 +607,7 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl,
int muxmode = -1;
int i;
mutex_lock(&state->mutex);
guard(mutex)(&state->mutex);
/*
* Figure out to which port the requested GPIO belongs and how to
@ -642,7 +642,6 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl,
* Error: The requested pin is already
* used for something else.
*/
mutex_unlock(&state->mutex);
return -EBUSY;
}
break;
@ -667,8 +666,6 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl,
if (muxport >= 0)
tb10x_pinctrl_set_config(state, muxport, muxmode);
mutex_unlock(&state->mutex);
return 0;
}
@ -695,34 +692,28 @@ static int tb10x_pctl_set_mux(struct pinctrl_dev *pctl,
if (grp->port < 0)
return 0;
mutex_lock(&state->mutex);
guard(mutex)(&state->mutex);
/*
* Check if the requested function is compatible with previously
* requested functions.
*/
if (state->ports[grp->port].count
&& (state->ports[grp->port].mode != grp->mode)) {
mutex_unlock(&state->mutex);
&& (state->ports[grp->port].mode != grp->mode))
return -EBUSY;
}
/*
* Check if the requested function is compatible with previously
* requested GPIOs.
*/
for (i = 0; i < grp->pincnt; i++)
if (test_bit(grp->pins[i], state->gpios)) {
mutex_unlock(&state->mutex);
if (test_bit(grp->pins[i], state->gpios))
return -EBUSY;
}
tb10x_pinctrl_set_config(state, grp->port, grp->mode);
state->ports[grp->port].count++;
mutex_unlock(&state->mutex);
return 0;
}

View file

@ -1729,6 +1729,26 @@ static const struct msm_gpio_wakeirq_map glymur_pdc_map[] = {
{ 232, 206 }, { 234, 172 }, { 235, 173 }, { 242, 158 }, { 244, 156 },
};
static const struct msm_gpio_wakeirq_map mahua_pdc_map[] = {
{ 0, 116 }, { 2, 114 }, { 3, 115 }, { 4, 175 }, { 5, 176 },
{ 7, 111 }, { 11, 129 }, { 13, 130 }, { 15, 112 }, { 19, 113 },
{ 23, 187 }, { 27, 188 }, { 28, 121 }, { 29, 122 }, { 30, 136 },
{ 31, 203 }, { 32, 189 }, { 34, 174 }, { 35, 190 }, { 36, 191 },
{ 39, 124 }, { 43, 192 }, { 47, 193 }, { 51, 123 }, { 53, 133 },
{ 55, 125 }, { 59, 131 }, { 64, 134 }, { 65, 150 }, { 66, 186 },
{ 67, 132 }, { 68, 195 }, { 71, 135 }, { 75, 196 }, { 79, 197 },
{ 83, 198 }, { 84, 181 }, { 85, 199 }, { 87, 200 }, { 91, 201 },
{ 92, 182 }, { 93, 183 }, { 94, 184 }, { 95, 185 }, { 98, 202 },
{ 105, 157 }, { 113, 128 }, { 121, 117 }, { 123, 118 }, { 125, 119 },
{ 129, 120 }, { 131, 126 }, { 132, 160 }, { 133, 194 }, { 134, 127 },
{ 141, 137 }, { 144, 138 }, { 145, 139 }, { 147, 140 }, { 148, 141 },
{ 150, 146 }, { 151, 147 }, { 153, 148 }, { 154, 144 }, { 155, 159 },
{ 156, 149 }, { 157, 151 }, { 163, 142 }, { 172, 143 }, { 181, 145 },
{ 193, 161 }, { 196, 152 }, { 203, 177 }, { 208, 178 }, { 215, 162 },
{ 217, 153 }, { 220, 154 }, { 221, 155 }, { 228, 179 }, { 230, 180 },
{ 232, 206 }, { 234, 172 }, { 235, 173 }, { 242, 158 }, { 244, 156 },
};
static const struct msm_pinctrl_soc_data glymur_tlmm = {
.pins = glymur_pins,
.npins = ARRAY_SIZE(glymur_pins),
@ -1742,14 +1762,34 @@ static const struct msm_pinctrl_soc_data glymur_tlmm = {
.egpio_func = 11,
};
static const struct msm_pinctrl_soc_data mahua_tlmm = {
.pins = glymur_pins,
.npins = ARRAY_SIZE(glymur_pins),
.functions = glymur_functions,
.nfunctions = ARRAY_SIZE(glymur_functions),
.groups = glymur_groups,
.ngroups = ARRAY_SIZE(glymur_groups),
.ngpios = 251,
.wakeirq_map = mahua_pdc_map,
.nwakeirq_map = ARRAY_SIZE(mahua_pdc_map),
.egpio_func = 11,
};
static const struct of_device_id glymur_tlmm_of_match[] = {
{ .compatible = "qcom,glymur-tlmm", },
{ }
{ .compatible = "qcom,glymur-tlmm", .data = &glymur_tlmm },
{ .compatible = "qcom,mahua-tlmm", .data = &mahua_tlmm },
{ },
};
static int glymur_tlmm_probe(struct platform_device *pdev)
{
return msm_pinctrl_probe(pdev, &glymur_tlmm);
const struct msm_pinctrl_soc_data *data;
data = of_device_get_match_data(&pdev->dev);
if (!data)
return -ENODEV;
return msm_pinctrl_probe(pdev, data);
}
static struct platform_driver glymur_tlmm_driver = {

View file

@ -73,7 +73,7 @@ static const char * const i2s1_ws_groups[] = { "gpio7" };
static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" };
static const char * const wsa_swr_clk_groups[] = { "gpio10" };
static const char * const wsa_swr_data_groups[] = { "gpio11" };
static const char * const i2s2_data_groups[] = { "gpio12", "gpio12" };
static const char * const i2s2_data_groups[] = { "gpio12", "gpio13" };
static const struct lpi_pingroup sm8250_groups[] = {
LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _),

View file

@ -308,9 +308,11 @@ config PINCTRL_RZT2H
bool "pin control support for RZ/N2H and RZ/T2H" if COMPILE_TEST
depends on 64BIT && OF
select GPIOLIB
select GPIOLIB_IRQCHIP
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select GENERIC_PINCONF
select IRQ_DOMAIN_HIERARCHY
help
This selects GPIO and pinctrl driver for Renesas RZ/T2H
platforms.

View file

@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>
@ -51,6 +52,7 @@
#define PFC_MASK GENMASK_ULL(5, 0)
#define PFC_PIN_MASK(pin) (PFC_MASK << ((pin) * 8))
#define PFC_FUNC_INTERRUPT 0
/*
* Use 16 lower bits [15:0] for pin identifier
@ -64,6 +66,9 @@
#define RZT2H_MAX_SAFETY_PORTS 12
#define RZT2H_INTERRUPTS_START 16
#define RZT2H_INTERRUPTS_NUM 17
struct rzt2h_pinctrl_data {
unsigned int n_port_pins;
const u8 *port_pin_configs;
@ -79,9 +84,11 @@ struct rzt2h_pinctrl {
struct device *dev;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range gpio_range;
DECLARE_BITMAP(used_irqs, RZT2H_INTERRUPTS_NUM);
spinlock_t lock; /* lock read/write registers */
struct mutex mutex; /* serialize adding groups and functions */
bool safety_port_enabled;
atomic_t wakeup_path;
};
#define RZT2H_GET_BASE(pctrl, port) \
@ -119,6 +126,19 @@ static int rzt2h_validate_pin(struct rzt2h_pinctrl *pctrl, unsigned int offset)
return (pincfg & BIT(pin)) ? 0 : -EINVAL;
}
static void rzt2h_pinctrl_set_gpio_en(struct rzt2h_pinctrl *pctrl,
u8 port, u8 pin, bool en)
{
u8 reg = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
if (en)
reg &= ~BIT(pin);
else
reg |= BIT(pin);
rzt2h_pinctrl_writeb(pctrl, port, reg, PMC(port));
}
static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl,
u8 port, u8 pin, u8 func)
{
@ -133,8 +153,7 @@ static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl,
rzt2h_pinctrl_writew(pctrl, port, reg16, PM(port));
/* Temporarily switch to GPIO mode with PMC register */
reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
rzt2h_pinctrl_writeb(pctrl, port, reg16 & ~BIT(pin), PMC(port));
rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, true);
/* Select Pin function mode with PFC register */
reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port));
@ -142,8 +161,7 @@ static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl,
rzt2h_pinctrl_writeq(pctrl, port, reg64 | ((u64)func << (pin * 8)), PFC(port));
/* Switch to Peripheral pin function with PMC register */
reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
rzt2h_pinctrl_writeb(pctrl, port, reg16 | BIT(pin), PMC(port));
rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, false);
}
static int rzt2h_pinctrl_set_mux(struct pinctrl_dev *pctldev,
@ -447,7 +465,6 @@ static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset)
u8 port = RZT2H_PIN_ID_TO_PORT(offset);
u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
int ret;
u8 reg;
ret = rzt2h_validate_pin(pctrl, offset);
if (ret)
@ -460,9 +477,7 @@ static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset)
guard(spinlock_irqsave)(&pctrl->lock);
/* Select GPIO mode in PMC Register */
reg = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
reg &= ~BIT(bit);
rzt2h_pinctrl_writeb(pctrl, port, reg, PMC(port));
rzt2h_pinctrl_set_gpio_en(pctrl, port, bit, true);
return 0;
}
@ -486,6 +501,7 @@ static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip);
u8 port = RZT2H_PIN_ID_TO_PORT(offset);
u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
u64 reg64;
u16 reg;
int ret;
@ -493,8 +509,25 @@ static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
if (ret)
return ret;
if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit))
guard(spinlock_irqsave)(&pctrl->lock);
if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit)) {
/*
* When a GPIO is being requested as an IRQ, the pinctrl
* framework expects to be able to read the GPIO's direction.
* IRQ function is separate from GPIO, and enabling it takes the
* pin out of GPIO mode.
* At this point, .child_to_parent_hwirq() has already been
* called to enable the IRQ function.
* Default to input direction for IRQ function.
*/
reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port));
reg64 = (reg64 >> (bit * 8)) & PFC_MASK;
if (reg64 == PFC_FUNC_INTERRUPT)
return GPIO_LINE_DIRECTION_IN;
return -EINVAL;
}
reg = rzt2h_pinctrl_readw(pctrl, port, PM(port));
reg = (reg >> (bit * 2)) & PM_MASK;
@ -617,14 +650,185 @@ static const char * const rzt2h_gpio_names[] = {
"P35_0", "P35_1", "P35_2", "P35_3", "P35_4", "P35_5", "P35_6", "P35_7",
};
/*
* Interrupts 0-15 are for INTCPUn, which are not exposed externally.
* Interrupts 16-31 are for IRQn. SEI is 32.
* This table matches the information found in User Manual's Section
* 17.5, Multiplexed Pin Configurations, Tables 17.5 to 17.40, on the
* Interrupt rows.
* RZ/N2H has the same GPIO to IRQ mapping, except for the pins which
* are not present.
*/
static const u8 rzt2h_gpio_irq_map[] = {
32, 16, 17, 18, 19, 0, 20, 21,
22, 0, 0, 0, 0, 0, 0, 0,
23, 24, 25, 26, 27, 0, 0, 0,
0, 0, 28, 29, 30, 31, 0, 0,
0, 0, 0, 0, 0, 32, 16, 17,
18, 19, 20, 21, 22, 0, 0, 0,
0, 0, 24, 25, 26, 27, 0, 28,
29, 30, 31, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 24, 32, 16,
0, 0, 0, 0, 0, 0, 0, 0,
20, 23, 17, 18, 19, 0, 16, 25,
29, 20, 21, 22, 23, 0, 0, 0,
0, 0, 0, 0, 17, 0, 0, 18,
0, 0, 19, 0, 0, 20, 0, 30,
21, 0, 0, 22, 0, 0, 24, 25,
0, 0, 0, 0, 0, 16, 17, 0,
18, 0, 0, 26, 27, 0, 0, 0,
28, 29, 30, 31, 0, 0, 0, 0,
23, 31, 32, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
27, 0, 0, 21, 22, 23, 24, 25,
26, 0, 0, 0, 0, 0, 0, 0,
27, 28, 29, 30, 31, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 28, 32, 16,
17, 18, 19, 0, 0, 0, 0, 20,
21, 22, 23, 0, 0, 0, 0, 0,
0, 0, 0, 0, 24, 25, 0, 0,
0, 0, 26, 27, 0, 0, 0, 30,
0, 29, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 28, 29, 30, 31, 0,
0, 0, 0, 0, 0, 0, 0, 30,
0, 0, 0, 0, 0, 0, 0, 0,
};
static void rzt2h_gpio_irq_disable(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
unsigned int hwirq = irqd_to_hwirq(d);
irq_chip_disable_parent(d);
gpiochip_disable_irq(gc, hwirq);
}
static void rzt2h_gpio_irq_enable(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
unsigned int hwirq = irqd_to_hwirq(d);
gpiochip_enable_irq(gc, hwirq);
irq_chip_enable_parent(d);
}
static int rzt2h_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct rzt2h_pinctrl *pctrl = container_of(gc, struct rzt2h_pinctrl, gpio_chip);
int ret;
ret = irq_chip_set_wake_parent(d, on);
if (ret)
return ret;
/*
* If any of the IRQs are in use, put the entire pin controller on the
* device wakeup path.
*/
if (on)
atomic_inc(&pctrl->wakeup_path);
else
atomic_dec(&pctrl->wakeup_path);
return 0;
}
static const struct irq_chip rzt2h_gpio_irqchip = {
.name = "rzt2h-gpio",
.irq_disable = rzt2h_gpio_irq_disable,
.irq_enable = rzt2h_gpio_irq_enable,
.irq_mask = irq_chip_mask_parent,
.irq_unmask = irq_chip_unmask_parent,
.irq_set_type = irq_chip_set_type_parent,
.irq_set_wake = rzt2h_gpio_irq_set_wake,
.irq_eoi = irq_chip_eoi_parent,
.irq_set_affinity = irq_chip_set_affinity_parent,
.flags = IRQCHIP_IMMUTABLE,
GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
static int rzt2h_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
unsigned int child,
unsigned int child_type,
unsigned int *parent,
unsigned int *parent_type)
{
struct rzt2h_pinctrl *pctrl = gpiochip_get_data(gc);
u8 port = RZT2H_PIN_ID_TO_PORT(child);
u8 pin = RZT2H_PIN_ID_TO_PIN(child);
u8 parent_irq;
parent_irq = rzt2h_gpio_irq_map[child];
if (parent_irq < RZT2H_INTERRUPTS_START)
return -EINVAL;
if (test_and_set_bit(parent_irq - RZT2H_INTERRUPTS_START,
pctrl->used_irqs))
return -EBUSY;
rzt2h_pinctrl_set_pfc_mode(pctrl, port, pin, PFC_FUNC_INTERRUPT);
*parent = parent_irq;
*parent_type = child_type;
return 0;
}
static void rzt2h_gpio_irq_domain_free(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs)
{
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct rzt2h_pinctrl *pctrl = container_of(gc, struct rzt2h_pinctrl, gpio_chip);
irq_hw_number_t hwirq = irqd_to_hwirq(d);
u8 port = RZT2H_PIN_ID_TO_PORT(hwirq);
u8 pin = RZT2H_PIN_ID_TO_PIN(hwirq);
if (test_and_clear_bit(hwirq - RZT2H_INTERRUPTS_START, pctrl->used_irqs))
rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, false);
irq_domain_free_irqs_common(domain, virq, nr_irqs);
}
static void rzt2h_gpio_init_irq_valid_mask(struct gpio_chip *gc,
unsigned long *valid_mask,
unsigned int ngpios)
{
struct rzt2h_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned int offset;
for (offset = 0; offset < ngpios; offset++) {
if (!rzt2h_gpio_irq_map[offset] || rzt2h_validate_pin(pctrl, offset))
clear_bit(offset, valid_mask);
}
}
static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl)
{
struct pinctrl_gpio_range *range = &pctrl->gpio_range;
struct gpio_chip *chip = &pctrl->gpio_chip;
struct device_node *np = pctrl->dev->of_node;
struct irq_domain *parent_domain;
struct device *dev = pctrl->dev;
struct of_phandle_args of_args;
struct device_node *parent_np;
struct gpio_irq_chip *girq;
int ret;
parent_np = of_irq_find_parent(np);
if (!parent_np)
return -ENXIO;
parent_domain = irq_find_host(parent_np);
of_node_put(parent_np);
if (!parent_domain)
return -EPROBE_DEFER;
ret = of_parse_phandle_with_fixed_args(dev->of_node, "gpio-ranges", 3, 0, &of_args);
if (ret)
return dev_err_probe(dev, ret, "Unable to parse gpio-ranges\n");
@ -648,6 +852,17 @@ static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl)
chip->set = rzt2h_gpio_set;
chip->label = dev_name(dev);
if (of_property_present(np, "interrupt-controller")) {
girq = &chip->irq;
gpio_irq_chip_set_chip(girq, &rzt2h_gpio_irqchip);
girq->fwnode = dev_fwnode(pctrl->dev);
girq->parent_domain = parent_domain;
girq->child_to_parent_hwirq = rzt2h_gpio_child_to_parent_hwirq;
girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell;
girq->child_irq_domain_ops.free = rzt2h_gpio_irq_domain_free;
girq->init_valid_mask = rzt2h_gpio_init_irq_valid_mask;
}
range->id = 0;
range->pin_base = 0;
range->base = 0;
@ -792,10 +1007,25 @@ static const struct of_device_id rzt2h_pinctrl_of_table[] = {
{ /* sentinel */ }
};
static int rzt2h_pinctrl_suspend_noirq(struct device *dev)
{
struct rzt2h_pinctrl *pctrl = dev_get_drvdata(dev);
if (atomic_read(&pctrl->wakeup_path))
device_set_wakeup_path(dev);
return 0;
}
static const struct dev_pm_ops rzt2h_pinctrl_pm_ops = {
NOIRQ_SYSTEM_SLEEP_PM_OPS(rzt2h_pinctrl_suspend_noirq, NULL)
};
static struct platform_driver rzt2h_pinctrl_driver = {
.driver = {
.name = DRV_NAME,
.of_match_table = of_match_ptr(rzt2h_pinctrl_of_table),
.pm = pm_sleep_ptr(&rzt2h_pinctrl_pm_ops),
.suppress_bind_attrs = true,
},
.probe = rzt2h_pinctrl_probe,

View file

@ -1770,6 +1770,123 @@ const struct samsung_pinctrl_of_match_data exynos8895_of_data __initconst = {
.num_ctrl = ARRAY_SIZE(exynos8895_pin_ctrl),
};
/* pin banks of exynos9610 pin-controller 0 (ALIVE) */
static const struct samsung_pin_bank_data exynos9610_pin_banks0[] __initconst = {
EXYNOS850_PIN_BANK_EINTN(6, 0x000, "etc0"),
GS101_PIN_BANK_EINTW(8, 0x020, "gpa0", 0x00, 0x00),
GS101_PIN_BANK_EINTW(8, 0x040, "gpa1", 0x04, 0x08),
GS101_PIN_BANK_EINTW(8, 0x060, "gpa2", 0x08, 0x0c),
EXYNOS850_PIN_BANK_EINTN(5, 0x080, "gpq0"),
};
/* pin banks of exynos9610 pin-controller 1 (CMGP) */
static const struct samsung_pin_bank_data exynos9610_pin_banks1[] __initconst = {
EXYNOS850_PIN_BANK_EINTW(1, 0x000, "gpm0", 0x00),
EXYNOS850_PIN_BANK_EINTW(1, 0x020, "gpm1", 0x04),
EXYNOS850_PIN_BANK_EINTW(1, 0x040, "gpm2", 0x08),
EXYNOS850_PIN_BANK_EINTW(1, 0x060, "gpm3", 0x0C),
EXYNOS850_PIN_BANK_EINTW(1, 0x080, "gpm4", 0x10),
EXYNOS850_PIN_BANK_EINTW(1, 0x0A0, "gpm5", 0x14),
EXYNOS850_PIN_BANK_EINTW(1, 0x0C0, "gpm6", 0x18),
EXYNOS850_PIN_BANK_EINTW(1, 0x0E0, "gpm7", 0x1C),
EXYNOS850_PIN_BANK_EINTW(1, 0x100, "gpm8", 0x20),
EXYNOS850_PIN_BANK_EINTW(1, 0x120, "gpm9", 0x24),
EXYNOS850_PIN_BANK_EINTW(1, 0x140, "gpm10", 0x28),
EXYNOS850_PIN_BANK_EINTW(1, 0x160, "gpm11", 0x2C),
EXYNOS850_PIN_BANK_EINTW(1, 0x180, "gpm12", 0x30),
EXYNOS850_PIN_BANK_EINTW(1, 0x1A0, "gpm13", 0x34),
EXYNOS850_PIN_BANK_EINTW(1, 0x1C0, "gpm14", 0x38),
EXYNOS850_PIN_BANK_EINTW(1, 0x1E0, "gpm15", 0x3C),
EXYNOS850_PIN_BANK_EINTW(1, 0x200, "gpm16", 0x40),
EXYNOS850_PIN_BANK_EINTW(1, 0x220, "gpm17", 0x44),
EXYNOS850_PIN_BANK_EINTW(1, 0x240, "gpm18", 0x48),
EXYNOS850_PIN_BANK_EINTW(1, 0x260, "gpm19", 0x4C),
EXYNOS850_PIN_BANK_EINTW(1, 0x280, "gpm20", 0x50),
EXYNOS850_PIN_BANK_EINTW(1, 0x2A0, "gpm21", 0x54),
EXYNOS850_PIN_BANK_EINTW(1, 0x2C0, "gpm22", 0x58),
EXYNOS850_PIN_BANK_EINTW(1, 0x2E0, "gpm23", 0x5C),
EXYNOS850_PIN_BANK_EINTW(1, 0x300, "gpm24", 0x60),
EXYNOS850_PIN_BANK_EINTW(1, 0x320, "gpm25", 0x64),
};
/* pin banks of exynos9610 pin-controller 2 (DISPAUD) */
static const struct samsung_pin_bank_data exynos9610_pin_banks2[] __initconst = {
GS101_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00, 0x00),
GS101_PIN_BANK_EINTG(4, 0x020, "gpb1", 0x04, 0x08),
GS101_PIN_BANK_EINTG(5, 0x040, "gpb2", 0x08, 0x0c),
};
/* pin banks of exynos9610 pin-controller 3 (FSYS) */
static const struct samsung_pin_bank_data exynos9610_pin_banks3[] __initconst = {
GS101_PIN_BANK_EINTG(4, 0x000, "gpf0", 0x00, 0x00),
GS101_PIN_BANK_EINTG(8, 0x020, "gpf1", 0x04, 0x04),
GS101_PIN_BANK_EINTG(6, 0x040, "gpf2", 0x08, 0x0c),
};
/* pin banks of exynos9610 pin-controller 4 (TOP) */
static const struct samsung_pin_bank_data exynos9610_pin_banks4[] __initconst = {
GS101_PIN_BANK_EINTG(8, 0x000, "gpp0", 0x00, 0x00),
GS101_PIN_BANK_EINTG(6, 0x020, "gpp1", 0x04, 0x08),
GS101_PIN_BANK_EINTG(8, 0x040, "gpp2", 0x08, 0x10),
GS101_PIN_BANK_EINTG(8, 0x060, "gpc0", 0x0C, 0x18),
GS101_PIN_BANK_EINTG(8, 0x080, "gpc1", 0x10, 0x20),
GS101_PIN_BANK_EINTG(5, 0x0A0, "gpc2", 0x14, 0x28),
GS101_PIN_BANK_EINTG(8, 0x0C0, "gpg0", 0x18, 0x30),
GS101_PIN_BANK_EINTG(8, 0x0E0, "gpg1", 0x1C, 0x38),
GS101_PIN_BANK_EINTG(8, 0x100, "gpg2", 0x20, 0x40),
GS101_PIN_BANK_EINTG(6, 0x120, "gpg3", 0x24, 0x48),
GS101_PIN_BANK_EINTG(3, 0x140, "gpg4", 0x28, 0x50),
};
/* pin banks of exynos9610 pin-controller 5 (SHUB) */
static const struct samsung_pin_bank_data exynos9610_pin_banks5[] __initconst = {
EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gph0", 0x00),
EXYNOS850_PIN_BANK_EINTG(3, 0x020, "gph1", 0x04),
};
static const struct samsung_pin_ctrl exynos9610_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 ALIVE data */
.pin_banks = exynos9610_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks0),
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 1 CMGP data */
.pin_banks = exynos9610_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks1),
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 2 DISPAUD data */
.pin_banks = exynos9610_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks2),
}, {
/* pin-controller instance 3 FSYS data */
.pin_banks = exynos9610_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks3),
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 4 TOP data */
.pin_banks = exynos9610_pin_banks4,
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks4),
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 5 SHUB data */
.pin_banks = exynos9610_pin_banks5,
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks5),
},
};
const struct samsung_pinctrl_of_match_data exynos9610_of_data __initconst = {
.ctrl = exynos9610_pin_ctrl,
.num_ctrl = ARRAY_SIZE(exynos9610_pin_ctrl),
};
/*
* Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
* gpio/pin-mux/pinconfig controllers.

View file

@ -1504,6 +1504,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
.data = &exynos8890_of_data },
{ .compatible = "samsung,exynos8895-pinctrl",
.data = &exynos8895_of_data },
{ .compatible = "samsung,exynos9610-pinctrl",
.data = &exynos9610_of_data },
{ .compatible = "samsung,exynos9810-pinctrl",
.data = &exynos9810_of_data },
{ .compatible = "samsung,exynos990-pinctrl",

View file

@ -398,6 +398,7 @@ extern const struct samsung_pinctrl_of_match_data exynos7885_of_data;
extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
extern const struct samsung_pinctrl_of_match_data exynos8890_of_data;
extern const struct samsung_pinctrl_of_match_data exynos8895_of_data;
extern const struct samsung_pinctrl_of_match_data exynos9610_of_data;
extern const struct samsung_pinctrl_of_match_data exynos9810_of_data;
extern const struct samsung_pinctrl_of_match_data exynos990_of_data;
extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data;

View file

@ -6,11 +6,7 @@
#ifndef _PINCTRL_SOPHGO_CV18XX_H
#define _PINCTRL_SOPHGO_CV18XX_H
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>

View file

@ -6,12 +6,6 @@
#ifndef _PINCTRL_SOPHGO_SG2042_H
#define _PINCTRL_SOPHGO_SG2042_H
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>

View file

@ -4,7 +4,7 @@
#
config PINCTRL_SPACEMIT_K1
bool "SpacemiT K1 SoC Pinctrl driver"
bool "SpacemiT K1/K3 SoC Pinctrl driver"
depends on ARCH_SPACEMIT || COMPILE_TEST
depends on OF
default ARCH_SPACEMIT
@ -12,7 +12,7 @@ config PINCTRL_SPACEMIT_K1
select GENERIC_PINMUX_FUNCTIONS
select GENERIC_PINCONF
help
Say Y to select the pinctrl driver for K1 SoC.
Say Y to select the pinctrl driver for K1/K3 SoC.
This pin controller allows selecting the mux function for
each pin. This driver can also be built as a module called
pinctrl-k1.

View file

@ -7,8 +7,10 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/mutex.h>
@ -24,11 +26,12 @@
#include "pinctrl-k1.h"
/*
* +---------+----------+-----------+--------+--------+----------+--------+
* | pull | drive | schmitter | slew | edge | strong | mux |
* | up/down | strength | trigger | rate | detect | pull | mode |
* +---------+----------+-----------+--------+--------+----------+--------+
* 3 bits 3 bits 2 bits 1 bit 3 bits 1 bit 3 bits
* | pull | drive | schmitter | slew | edge | strong | mux |
* SoC | up/down | strength | trigger | rate | detect | pull | mode |
*-----+---------+----------+-----------+-------+--------+--------+--------+
* K1 | 3 bits | 3 bits | 2 bits | 1 bit | 3 bits | 1 bit | 3 bits |
*-----+---------+----------+-----------+-------+--------+--------+--------+
* K3 | 3 bits | 4 bits | 1 bits | 1 bit | 3 bits | 1 bit | 3 bits |
*/
#define PAD_MUX GENMASK(2, 0)
@ -38,12 +41,50 @@
#define PAD_EDGE_CLEAR BIT(6)
#define PAD_SLEW_RATE GENMASK(12, 11)
#define PAD_SLEW_RATE_EN BIT(7)
#define PAD_SCHMITT GENMASK(9, 8)
#define PAD_DRIVE GENMASK(12, 10)
#define PAD_SCHMITT_K1 GENMASK(9, 8)
#define PAD_DRIVE_K1 GENMASK(12, 10)
#define PAD_SCHMITT_K3 BIT(8)
#define PAD_DRIVE_K3 GENMASK(12, 9)
#define PAD_PULLDOWN BIT(13)
#define PAD_PULLUP BIT(14)
#define PAD_PULL_EN BIT(15)
#define IO_PWR_DOMAIN_OFFSET 0x800
#define IO_PWR_DOMAIN_GPIO2_Kx 0x0c
#define IO_PWR_DOMAIN_MMC_Kx 0x1c
#define IO_PWR_DOMAIN_GPIO3_K1 0x10
#define IO_PWR_DOMAIN_QSPI_K1 0x20
#define IO_PWR_DOMAIN_GPIO1_K3 0x04
#define IO_PWR_DOMAIN_GPIO5_K3 0x10
#define IO_PWR_DOMAIN_GPIO4_K3 0x20
#define IO_PWR_DOMAIN_QSPI_K3 0x2c
#define IO_PWR_DOMAIN_V18EN BIT(2)
#define APBC_ASFAR 0x50
#define APBC_ASSAR 0x54
#define APBC_ASFAR_AKEY 0xbaba
#define APBC_ASSAR_AKEY 0xeb10
struct spacemit_pin_drv_strength {
u8 val;
u32 mA;
};
struct spacemit_pinctrl_dconf {
u64 schmitt_mask;
u64 drive_mask;
struct spacemit_pin_drv_strength *ds_1v8_tbl;
size_t ds_1v8_tbl_num;
struct spacemit_pin_drv_strength *ds_3v3_tbl;
size_t ds_3v3_tbl_num;
};
struct spacemit_pin {
u16 pin;
u16 flags;
@ -60,12 +101,17 @@ struct spacemit_pinctrl {
raw_spinlock_t lock;
void __iomem *regs;
struct regmap *regmap_apbc;
};
struct spacemit_pinctrl_data {
const struct pinctrl_pin_desc *pins;
const struct spacemit_pin *data;
u16 npins;
unsigned int (*pin_to_offset)(unsigned int pin);
unsigned int (*pin_to_io_pd_offset)(unsigned int pin);
const struct spacemit_pinctrl_dconf *dconf;
};
struct spacemit_pin_mux_config {
@ -73,13 +119,8 @@ struct spacemit_pin_mux_config {
u32 config;
};
struct spacemit_pin_drv_strength {
u8 val;
u32 mA;
};
/* map pin id to pinctrl register offset, refer MFPR definition */
static unsigned int spacemit_pin_to_offset(unsigned int pin)
static unsigned int spacemit_k1_pin_to_offset(unsigned int pin)
{
unsigned int offset = 0;
@ -124,10 +165,67 @@ static unsigned int spacemit_pin_to_offset(unsigned int pin)
return offset << 2;
}
static unsigned int spacemit_k3_pin_to_offset(unsigned int pin)
{
unsigned int offset = pin > 130 ? (pin + 2) : pin;
return offset << 2;
}
static unsigned int spacemit_k1_pin_to_io_pd_offset(unsigned int pin)
{
unsigned int offset = 0;
switch (pin) {
case 47 ... 52:
offset = IO_PWR_DOMAIN_GPIO3_K1;
break;
case 75 ... 80:
offset = IO_PWR_DOMAIN_GPIO2_Kx;
break;
case 98 ... 103:
offset = IO_PWR_DOMAIN_QSPI_K1;
break;
case 104 ... 109:
offset = IO_PWR_DOMAIN_MMC_Kx;
break;
}
return offset;
}
static unsigned int spacemit_k3_pin_to_io_pd_offset(unsigned int pin)
{
unsigned int offset = 0;
switch (pin) {
case 0 ... 20:
offset = IO_PWR_DOMAIN_GPIO1_K3;
break;
case 21 ... 41:
offset = IO_PWR_DOMAIN_GPIO2_Kx;
break;
case 76 ... 98:
offset = IO_PWR_DOMAIN_GPIO4_K3;
break;
case 99 ... 127:
offset = IO_PWR_DOMAIN_GPIO5_K3;
break;
case 132 ... 137:
offset = IO_PWR_DOMAIN_MMC_Kx;
break;
case 138 ... 144:
offset = IO_PWR_DOMAIN_QSPI_K3;
break;
}
return offset;
}
static inline void __iomem *spacemit_pin_to_reg(struct spacemit_pinctrl *pctrl,
unsigned int pin)
{
return pctrl->regs + spacemit_pin_to_offset(pin);
return pctrl->regs + pctrl->data->pin_to_offset(pin);
}
static u16 spacemit_dt_get_pin(u32 value)
@ -177,7 +275,7 @@ static void spacemit_pctrl_dbg_show(struct pinctrl_dev *pctldev,
void __iomem *reg;
u32 value;
seq_printf(seq, "offset: 0x%04x ", spacemit_pin_to_offset(pin));
seq_printf(seq, "offset: 0x%04x ", pctrl->data->pin_to_offset(pin));
seq_printf(seq, "type: %s ", io_type_desc[type]);
reg = spacemit_pin_to_reg(pctrl, pin);
@ -185,23 +283,70 @@ static void spacemit_pctrl_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(seq, "mux: %ld reg: 0x%04x", (value & PAD_MUX), value);
}
/* use IO high level output current as the table */
static struct spacemit_pin_drv_strength spacemit_ds_1v8_tbl[4] = {
{ 0, 11 },
{ 2, 21 },
{ 4, 32 },
{ 6, 42 },
static const struct spacemit_pinctrl_dconf k1_drive_conf = {
.drive_mask = PAD_DRIVE_K1,
.schmitt_mask = PAD_SCHMITT_K1,
.ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) {
{ 0, 11 },
{ 2, 21 },
{ 4, 32 },
{ 6, 42 },
},
.ds_1v8_tbl_num = 4,
.ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) {
{ 0, 7 },
{ 2, 10 },
{ 4, 13 },
{ 6, 16 },
{ 1, 19 },
{ 3, 23 },
{ 5, 26 },
{ 7, 29 },
},
.ds_3v3_tbl_num = 8,
};
static struct spacemit_pin_drv_strength spacemit_ds_3v3_tbl[8] = {
{ 0, 7 },
{ 2, 10 },
{ 4, 13 },
{ 6, 16 },
{ 1, 19 },
{ 3, 23 },
{ 5, 26 },
{ 7, 29 },
static const struct spacemit_pinctrl_dconf k3_drive_conf = {
.drive_mask = PAD_DRIVE_K3,
.schmitt_mask = PAD_SCHMITT_K3,
.ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) {
{ 0, 2 },
{ 1, 4 },
{ 2, 6 },
{ 3, 7 },
{ 4, 9 },
{ 5, 11 },
{ 6, 13 },
{ 7, 14 },
{ 8, 21 },
{ 9, 23 },
{ 10, 25 },
{ 11, 26 },
{ 12, 28 },
{ 13, 30 },
{ 14, 31 },
{ 15, 33 },
},
.ds_1v8_tbl_num = 16,
.ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) {
{ 0, 3 },
{ 1, 5 },
{ 2, 7 },
{ 3, 9 },
{ 4, 11 },
{ 5, 13 },
{ 6, 15 },
{ 7, 17 },
{ 8, 25 },
{ 9, 27 },
{ 10, 29 },
{ 11, 31 },
{ 12, 33 },
{ 13, 35 },
{ 14, 37 },
{ 15, 38 },
},
.ds_3v3_tbl_num = 16,
};
static inline u8 spacemit_get_ds_value(struct spacemit_pin_drv_strength *tbl,
@ -229,16 +374,17 @@ static inline u32 spacemit_get_ds_mA(struct spacemit_pin_drv_strength *tbl,
}
static inline u8 spacemit_get_driver_strength(enum spacemit_pin_io_type type,
const struct spacemit_pinctrl_dconf *dconf,
u32 mA)
{
switch (type) {
case IO_TYPE_1V8:
return spacemit_get_ds_value(spacemit_ds_1v8_tbl,
ARRAY_SIZE(spacemit_ds_1v8_tbl),
return spacemit_get_ds_value(dconf->ds_1v8_tbl,
dconf->ds_1v8_tbl_num,
mA);
case IO_TYPE_3V3:
return spacemit_get_ds_value(spacemit_ds_3v3_tbl,
ARRAY_SIZE(spacemit_ds_3v3_tbl),
return spacemit_get_ds_value(dconf->ds_3v3_tbl,
dconf->ds_3v3_tbl_num,
mA);
default:
return 0;
@ -246,16 +392,17 @@ static inline u8 spacemit_get_driver_strength(enum spacemit_pin_io_type type,
}
static inline u32 spacemit_get_drive_strength_mA(enum spacemit_pin_io_type type,
const struct spacemit_pinctrl_dconf *dconf,
u32 value)
{
switch (type) {
case IO_TYPE_1V8:
return spacemit_get_ds_mA(spacemit_ds_1v8_tbl,
ARRAY_SIZE(spacemit_ds_1v8_tbl),
value & 0x6);
return spacemit_get_ds_mA(dconf->ds_1v8_tbl,
dconf->ds_1v8_tbl_num,
value);
case IO_TYPE_3V3:
return spacemit_get_ds_mA(spacemit_ds_3v3_tbl,
ARRAY_SIZE(spacemit_ds_3v3_tbl),
return spacemit_get_ds_mA(dconf->ds_3v3_tbl,
dconf->ds_3v3_tbl_num,
value);
default:
return 0;
@ -294,6 +441,42 @@ static int spacemit_pctrl_check_power(struct pinctrl_dev *pctldev,
return 0;
}
static void spacemit_set_io_pwr_domain(struct spacemit_pinctrl *pctrl,
const struct spacemit_pin *spin,
const enum spacemit_pin_io_type type)
{
u32 offset, val = 0;
if (!pctrl->regmap_apbc)
return;
offset = pctrl->data->pin_to_io_pd_offset(spin->pin);
/* Other bits are reserved so don't need to save them */
if (type == IO_TYPE_1V8)
val = IO_PWR_DOMAIN_V18EN;
/*
* IO power domain registers are protected and cannot be accessed
* directly. Before performing any read or write to the IO power
* domain registers, an explicit unlock sequence must be issued
* via the AIB Secure Access Register (ASAR).
*
* The unlock sequence allows exactly one subsequent access to the
* IO power domain registers. After that access completes, the ASAR
* keys are automatically cleared, and the registers become locked
* again.
*
* This mechanism ensures that IO power domain configuration is
* performed intentionally, as incorrect voltage settings may
* result in functional failures or hardware damage.
*/
regmap_write(pctrl->regmap_apbc, APBC_ASFAR, APBC_ASFAR_AKEY);
regmap_write(pctrl->regmap_apbc, APBC_ASSAR, APBC_ASSAR_AKEY);
writel_relaxed(val, pctrl->regs + IO_PWR_DOMAIN_OFFSET + offset);
}
static int spacemit_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **maps,
@ -501,7 +684,9 @@ static int spacemit_pinconf_get(struct pinctrl_dev *pctldev,
#define ENABLE_DRV_STRENGTH BIT(1)
#define ENABLE_SLEW_RATE BIT(2)
static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin,
static int spacemit_pinconf_generate_config(struct spacemit_pinctrl *pctrl,
const struct spacemit_pin *spin,
const struct spacemit_pinctrl_dconf *dconf,
unsigned long *configs,
unsigned int num_configs,
u32 *value)
@ -539,8 +724,8 @@ static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin,
drv_strength = arg;
break;
case PIN_CONFIG_INPUT_SCHMITT:
v &= ~PAD_SCHMITT;
v |= FIELD_PREP(PAD_SCHMITT, arg);
v &= ~dconf->schmitt_mask;
v |= (arg << __ffs(dconf->schmitt_mask)) & dconf->schmitt_mask;
break;
case PIN_CONFIG_POWER_SOURCE:
voltage = arg;
@ -574,12 +759,13 @@ static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin,
default:
return -EINVAL;
}
spacemit_set_io_pwr_domain(pctrl, spin, type);
}
val = spacemit_get_driver_strength(type, drv_strength);
val = spacemit_get_driver_strength(type, dconf, drv_strength);
v &= ~PAD_DRIVE;
v |= FIELD_PREP(PAD_DRIVE, val);
v &= ~dconf->drive_mask;
v |= (val << __ffs(dconf->drive_mask)) & dconf->drive_mask;
}
if (flag & ENABLE_SLEW_RATE) {
@ -629,7 +815,8 @@ static int spacemit_pinconf_set(struct pinctrl_dev *pctldev,
const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin);
u32 value;
if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value))
if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf,
configs, num_configs, &value))
return -EINVAL;
return spacemit_pin_set_config(pctrl, pin, value);
@ -651,7 +838,8 @@ static int spacemit_pinconf_group_set(struct pinctrl_dev *pctldev,
return -EINVAL;
spin = spacemit_get_pin(pctrl, group->grp.pins[0]);
if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value))
if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf,
configs, num_configs, &value))
return -EINVAL;
for (i = 0; i < group->grp.npins; i++)
@ -685,6 +873,7 @@ static void spacemit_pinconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *seq, unsigned int pin)
{
struct spacemit_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct spacemit_pinctrl_dconf *dconf = pctrl->data->dconf;
const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin);
enum spacemit_pin_io_type type = spacemit_to_pin_io_type(spin);
void __iomem *reg = spacemit_pin_to_reg(pctrl, pin);
@ -695,17 +884,17 @@ static void spacemit_pinconf_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(seq, ", io type (%s)", io_type_desc[type]);
tmp = FIELD_GET(PAD_DRIVE, value);
tmp = (value & dconf->drive_mask) >> __ffs(dconf->drive_mask);
if (type == IO_TYPE_1V8 || type == IO_TYPE_3V3) {
mA = spacemit_get_drive_strength_mA(type, tmp);
mA = spacemit_get_drive_strength_mA(type, dconf, tmp);
seq_printf(seq, ", drive strength (%d mA)", mA);
}
/* drive strength depend on power source, so show all values */
if (type == IO_TYPE_EXTERNAL)
seq_printf(seq, ", drive strength (%d or %d mA)",
spacemit_get_drive_strength_mA(IO_TYPE_1V8, tmp),
spacemit_get_drive_strength_mA(IO_TYPE_3V3, tmp));
spacemit_get_drive_strength_mA(IO_TYPE_1V8, dconf, tmp),
spacemit_get_drive_strength_mA(IO_TYPE_3V3, dconf, tmp));
seq_printf(seq, ", register (0x%04x)", value);
}
@ -720,6 +909,7 @@ static const struct pinconf_ops spacemit_pinconf_ops = {
static int spacemit_pinctrl_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
struct spacemit_pinctrl *pctrl;
struct clk *func_clk, *bus_clk;
@ -741,6 +931,12 @@ static int spacemit_pinctrl_probe(struct platform_device *pdev)
if (IS_ERR(pctrl->regs))
return PTR_ERR(pctrl->regs);
pctrl->regmap_apbc = syscon_regmap_lookup_by_phandle(np, "spacemit,apbc");
if (IS_ERR(pctrl->regmap_apbc)) {
dev_warn(dev, "no syscon found, disable power voltage switch functionality\n");
pctrl->regmap_apbc = NULL;
}
func_clk = devm_clk_get_enabled(dev, "func");
if (IS_ERR(func_clk))
return dev_err_probe(dev, PTR_ERR(func_clk), "failed to get func clock\n");
@ -1042,10 +1238,352 @@ static const struct spacemit_pinctrl_data k1_pinctrl_data = {
.pins = k1_pin_desc,
.data = k1_pin_data,
.npins = ARRAY_SIZE(k1_pin_desc),
.pin_to_offset = spacemit_k1_pin_to_offset,
.pin_to_io_pd_offset = spacemit_k1_pin_to_io_pd_offset,
.dconf = &k1_drive_conf,
};
static const struct pinctrl_pin_desc k3_pin_desc[] = {
PINCTRL_PIN(0, "GPIO_00"),
PINCTRL_PIN(1, "GPIO_01"),
PINCTRL_PIN(2, "GPIO_02"),
PINCTRL_PIN(3, "GPIO_03"),
PINCTRL_PIN(4, "GPIO_04"),
PINCTRL_PIN(5, "GPIO_05"),
PINCTRL_PIN(6, "GPIO_06"),
PINCTRL_PIN(7, "GPIO_07"),
PINCTRL_PIN(8, "GPIO_08"),
PINCTRL_PIN(9, "GPIO_09"),
PINCTRL_PIN(10, "GPIO_10"),
PINCTRL_PIN(11, "GPIO_11"),
PINCTRL_PIN(12, "GPIO_12"),
PINCTRL_PIN(13, "GPIO_13"),
PINCTRL_PIN(14, "GPIO_14"),
PINCTRL_PIN(15, "GPIO_15"),
PINCTRL_PIN(16, "GPIO_16"),
PINCTRL_PIN(17, "GPIO_17"),
PINCTRL_PIN(18, "GPIO_18"),
PINCTRL_PIN(19, "GPIO_19"),
PINCTRL_PIN(20, "GPIO_20"),
PINCTRL_PIN(21, "GPIO_21"),
PINCTRL_PIN(22, "GPIO_22"),
PINCTRL_PIN(23, "GPIO_23"),
PINCTRL_PIN(24, "GPIO_24"),
PINCTRL_PIN(25, "GPIO_25"),
PINCTRL_PIN(26, "GPIO_26"),
PINCTRL_PIN(27, "GPIO_27"),
PINCTRL_PIN(28, "GPIO_28"),
PINCTRL_PIN(29, "GPIO_29"),
PINCTRL_PIN(30, "GPIO_30"),
PINCTRL_PIN(31, "GPIO_31"),
PINCTRL_PIN(32, "GPIO_32"),
PINCTRL_PIN(33, "GPIO_33"),
PINCTRL_PIN(34, "GPIO_34"),
PINCTRL_PIN(35, "GPIO_35"),
PINCTRL_PIN(36, "GPIO_36"),
PINCTRL_PIN(37, "GPIO_37"),
PINCTRL_PIN(38, "GPIO_38"),
PINCTRL_PIN(39, "GPIO_39"),
PINCTRL_PIN(40, "GPIO_40"),
PINCTRL_PIN(41, "GPIO_41"),
PINCTRL_PIN(42, "GPIO_42"),
PINCTRL_PIN(43, "GPIO_43"),
PINCTRL_PIN(44, "GPIO_44"),
PINCTRL_PIN(45, "GPIO_45"),
PINCTRL_PIN(46, "GPIO_46"),
PINCTRL_PIN(47, "GPIO_47"),
PINCTRL_PIN(48, "GPIO_48"),
PINCTRL_PIN(49, "GPIO_49"),
PINCTRL_PIN(50, "GPIO_50"),
PINCTRL_PIN(51, "GPIO_51"),
PINCTRL_PIN(52, "GPIO_52"),
PINCTRL_PIN(53, "GPIO_53"),
PINCTRL_PIN(54, "GPIO_54"),
PINCTRL_PIN(55, "GPIO_55"),
PINCTRL_PIN(56, "GPIO_56"),
PINCTRL_PIN(57, "GPIO_57"),
PINCTRL_PIN(58, "GPIO_58"),
PINCTRL_PIN(59, "GPIO_59"),
PINCTRL_PIN(60, "GPIO_60"),
PINCTRL_PIN(61, "GPIO_61"),
PINCTRL_PIN(62, "GPIO_62"),
PINCTRL_PIN(63, "GPIO_63"),
PINCTRL_PIN(64, "GPIO_64"),
PINCTRL_PIN(65, "GPIO_65"),
PINCTRL_PIN(66, "GPIO_66"),
PINCTRL_PIN(67, "GPIO_67"),
PINCTRL_PIN(68, "GPIO_68"),
PINCTRL_PIN(69, "GPIO_69"),
PINCTRL_PIN(70, "GPIO_70"),
PINCTRL_PIN(71, "GPIO_71"),
PINCTRL_PIN(72, "GPIO_72"),
PINCTRL_PIN(73, "GPIO_73"),
PINCTRL_PIN(74, "GPIO_74"),
PINCTRL_PIN(75, "GPIO_75"),
PINCTRL_PIN(76, "GPIO_76"),
PINCTRL_PIN(77, "GPIO_77"),
PINCTRL_PIN(78, "GPIO_78"),
PINCTRL_PIN(79, "GPIO_79"),
PINCTRL_PIN(80, "GPIO_80"),
PINCTRL_PIN(81, "GPIO_81"),
PINCTRL_PIN(82, "GPIO_82"),
PINCTRL_PIN(83, "GPIO_83"),
PINCTRL_PIN(84, "GPIO_84"),
PINCTRL_PIN(85, "GPIO_85"),
PINCTRL_PIN(86, "GPIO_86"),
PINCTRL_PIN(87, "GPIO_87"),
PINCTRL_PIN(88, "GPIO_88"),
PINCTRL_PIN(89, "GPIO_89"),
PINCTRL_PIN(90, "GPIO_90"),
PINCTRL_PIN(91, "GPIO_91"),
PINCTRL_PIN(92, "GPIO_92"),
PINCTRL_PIN(93, "GPIO_93"),
PINCTRL_PIN(94, "GPIO_94"),
PINCTRL_PIN(95, "GPIO_95"),
PINCTRL_PIN(96, "GPIO_96"),
PINCTRL_PIN(97, "GPIO_97"),
PINCTRL_PIN(98, "GPIO_98"),
PINCTRL_PIN(99, "GPIO_99"),
PINCTRL_PIN(100, "GPIO_100"),
PINCTRL_PIN(101, "GPIO_101"),
PINCTRL_PIN(102, "GPIO_102"),
PINCTRL_PIN(103, "GPIO_103"),
PINCTRL_PIN(104, "GPIO_104"),
PINCTRL_PIN(105, "GPIO_105"),
PINCTRL_PIN(106, "GPIO_106"),
PINCTRL_PIN(107, "GPIO_107"),
PINCTRL_PIN(108, "GPIO_108"),
PINCTRL_PIN(109, "GPIO_109"),
PINCTRL_PIN(110, "GPIO_110"),
PINCTRL_PIN(111, "GPIO_111"),
PINCTRL_PIN(112, "GPIO_112"),
PINCTRL_PIN(113, "GPIO_113"),
PINCTRL_PIN(114, "GPIO_114"),
PINCTRL_PIN(115, "GPIO_115"),
PINCTRL_PIN(116, "GPIO_116"),
PINCTRL_PIN(117, "GPIO_117"),
PINCTRL_PIN(118, "GPIO_118"),
PINCTRL_PIN(119, "GPIO_119"),
PINCTRL_PIN(120, "GPIO_120"),
PINCTRL_PIN(121, "GPIO_121"),
PINCTRL_PIN(122, "GPIO_122"),
PINCTRL_PIN(123, "GPIO_123"),
PINCTRL_PIN(124, "GPIO_124"),
PINCTRL_PIN(125, "GPIO_125"),
PINCTRL_PIN(126, "GPIO_126"),
PINCTRL_PIN(127, "GPIO_127"),
PINCTRL_PIN(128, "PWR_SCL"),
PINCTRL_PIN(129, "PWR_SDA"),
PINCTRL_PIN(130, "VCXO_EN"),
PINCTRL_PIN(131, "PMIC_INT_N"),
PINCTRL_PIN(132, "MMC1_DAT3"),
PINCTRL_PIN(133, "MMC1_DAT2"),
PINCTRL_PIN(134, "MMC1_DAT1"),
PINCTRL_PIN(135, "MMC1_DAT0"),
PINCTRL_PIN(136, "MMC1_CMD"),
PINCTRL_PIN(137, "MMC1_CLK"),
PINCTRL_PIN(138, "QSPI_DAT0"),
PINCTRL_PIN(139, "QSPI_DAT1"),
PINCTRL_PIN(140, "QSPI_DAT2"),
PINCTRL_PIN(141, "QSPI_DAT3"),
PINCTRL_PIN(142, "QSPI_CS0"),
PINCTRL_PIN(143, "QSPI_CS1"),
PINCTRL_PIN(144, "QSPI_CLK"),
PINCTRL_PIN(145, "PRI_TDI"),
PINCTRL_PIN(146, "PRI_TMS"),
PINCTRL_PIN(147, "PRI_TCK"),
PINCTRL_PIN(148, "PRI_TDO"),
PINCTRL_PIN(149, "PWR_SSP_SCLK"),
PINCTRL_PIN(150, "PWR_SSP_FRM"),
PINCTRL_PIN(151, "PWR_SSP_TXD"),
PINCTRL_PIN(152, "PWR_SSP_RXD"),
};
static const struct spacemit_pin k3_pin_data[ARRAY_SIZE(k3_pin_desc)] = {
/* GPIO1 bank */
K1_FUNC_PIN(0, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(1, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(2, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(3, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(4, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(5, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(6, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(7, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(8, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(9, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(10, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(11, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(12, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(13, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(14, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(15, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(16, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(17, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(18, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(19, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(20, 0, IO_TYPE_EXTERNAL),
/* GPIO2 bank */
K1_FUNC_PIN(21, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(22, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(23, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(24, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(25, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(26, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(27, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(28, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(29, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(30, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(31, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(32, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(33, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(34, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(35, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(36, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(37, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(38, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(39, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(40, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(41, 0, IO_TYPE_EXTERNAL),
/* GPIO3 bank */
K1_FUNC_PIN(42, 0, IO_TYPE_1V8),
K1_FUNC_PIN(43, 0, IO_TYPE_1V8),
K1_FUNC_PIN(44, 0, IO_TYPE_1V8),
K1_FUNC_PIN(45, 0, IO_TYPE_1V8),
K1_FUNC_PIN(46, 0, IO_TYPE_1V8),
K1_FUNC_PIN(47, 0, IO_TYPE_1V8),
K1_FUNC_PIN(48, 0, IO_TYPE_1V8),
K1_FUNC_PIN(49, 0, IO_TYPE_1V8),
K1_FUNC_PIN(50, 0, IO_TYPE_1V8),
K1_FUNC_PIN(51, 0, IO_TYPE_1V8),
K1_FUNC_PIN(52, 0, IO_TYPE_1V8),
K1_FUNC_PIN(53, 0, IO_TYPE_1V8),
K1_FUNC_PIN(54, 0, IO_TYPE_1V8),
K1_FUNC_PIN(55, 0, IO_TYPE_1V8),
K1_FUNC_PIN(56, 0, IO_TYPE_1V8),
K1_FUNC_PIN(57, 0, IO_TYPE_1V8),
K1_FUNC_PIN(58, 0, IO_TYPE_1V8),
K1_FUNC_PIN(59, 0, IO_TYPE_1V8),
K1_FUNC_PIN(60, 0, IO_TYPE_1V8),
K1_FUNC_PIN(61, 0, IO_TYPE_1V8),
K1_FUNC_PIN(62, 0, IO_TYPE_1V8),
K1_FUNC_PIN(63, 0, IO_TYPE_1V8),
K1_FUNC_PIN(64, 0, IO_TYPE_1V8),
K1_FUNC_PIN(65, 0, IO_TYPE_1V8),
K1_FUNC_PIN(66, 0, IO_TYPE_1V8),
K1_FUNC_PIN(67, 0, IO_TYPE_1V8),
K1_FUNC_PIN(68, 0, IO_TYPE_1V8),
K1_FUNC_PIN(69, 0, IO_TYPE_1V8),
K1_FUNC_PIN(70, 0, IO_TYPE_1V8),
K1_FUNC_PIN(71, 0, IO_TYPE_1V8),
K1_FUNC_PIN(72, 0, IO_TYPE_1V8),
K1_FUNC_PIN(73, 0, IO_TYPE_1V8),
K1_FUNC_PIN(74, 0, IO_TYPE_1V8),
K1_FUNC_PIN(75, 0, IO_TYPE_1V8),
/* GPIO4 bank */
K1_FUNC_PIN(76, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(77, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(78, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(79, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(80, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(81, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(82, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(83, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(84, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(85, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(86, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(87, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(88, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(89, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(90, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(91, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(92, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(93, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(94, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(95, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(96, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(97, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(98, 0, IO_TYPE_EXTERNAL),
/* GPIO5 bank */
K1_FUNC_PIN(99, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(100, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(101, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(102, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(103, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(104, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(105, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(106, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(107, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(108, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(109, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(110, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(111, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(112, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(113, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(114, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(115, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(116, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(117, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(118, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(119, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(120, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(121, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(122, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(123, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(124, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(125, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(126, 0, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(127, 0, IO_TYPE_EXTERNAL),
/* PMIC */
K1_FUNC_PIN(128, 0, IO_TYPE_1V8),
K1_FUNC_PIN(129, 0, IO_TYPE_1V8),
K1_FUNC_PIN(130, 0, IO_TYPE_1V8),
K1_FUNC_PIN(131, 0, IO_TYPE_1V8),
/* SD/MMC1 */
K1_FUNC_PIN(132, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(133, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(134, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(135, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(136, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(137, 1, IO_TYPE_EXTERNAL),
/* QSPI */
K1_FUNC_PIN(138, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(139, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(140, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(141, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(142, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(143, 1, IO_TYPE_EXTERNAL),
K1_FUNC_PIN(144, 1, IO_TYPE_EXTERNAL),
/* PMIC */
K1_FUNC_PIN(145, 1, IO_TYPE_1V8),
K1_FUNC_PIN(146, 1, IO_TYPE_1V8),
K1_FUNC_PIN(147, 1, IO_TYPE_1V8),
K1_FUNC_PIN(148, 1, IO_TYPE_1V8),
K1_FUNC_PIN(149, 1, IO_TYPE_1V8),
K1_FUNC_PIN(150, 1, IO_TYPE_1V8),
K1_FUNC_PIN(151, 1, IO_TYPE_1V8),
K1_FUNC_PIN(152, 1, IO_TYPE_1V8),
};
static const struct spacemit_pinctrl_data k3_pinctrl_data = {
.pins = k3_pin_desc,
.data = k3_pin_data,
.npins = ARRAY_SIZE(k3_pin_desc),
.pin_to_offset = spacemit_k3_pin_to_offset,
.pin_to_io_pd_offset = spacemit_k3_pin_to_io_pd_offset,
.dconf = &k3_drive_conf,
};
static const struct of_device_id k1_pinctrl_ids[] = {
{ .compatible = "spacemit,k1-pinctrl", .data = &k1_pinctrl_data },
{ .compatible = "spacemit,k3-pinctrl", .data = &k3_pinctrl_data },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, k1_pinctrl_ids);
@ -1061,5 +1599,5 @@ static struct platform_driver k1_pinctrl_driver = {
builtin_platform_driver(k1_pinctrl_driver);
MODULE_AUTHOR("Yixun Lan <dlan@gentoo.org>");
MODULE_DESCRIPTION("Pinctrl driver for the SpacemiT K1 SoC");
MODULE_DESCRIPTION("Pinctrl driver for the SpacemiT K1/K3 SoC");
MODULE_LICENSE("GPL");

View file

@ -7,14 +7,11 @@
*/
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
#include <linux/pinctrl/pinctrl.h>

View file

@ -474,14 +474,14 @@ static const struct pinconf_ops tegra_xusb_padctl_pinconf_ops = {
#endif
};
static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
static void tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
{
u32 value;
mutex_lock(&padctl->lock);
guard(mutex)(&padctl->lock);
if (padctl->enable++ > 0)
goto out;
return;
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
@ -498,23 +498,19 @@ static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
out:
mutex_unlock(&padctl->lock);
return 0;
}
static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
static void tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
{
u32 value;
mutex_lock(&padctl->lock);
guard(mutex)(&padctl->lock);
if (WARN_ON(padctl->enable == 0))
goto out;
return;
if (--padctl->enable > 0)
goto out;
return;
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
@ -531,24 +527,24 @@ static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
out:
mutex_unlock(&padctl->lock);
return 0;
}
static int tegra_xusb_phy_init(struct phy *phy)
{
struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
return tegra_xusb_padctl_enable(padctl);
tegra_xusb_padctl_enable(padctl);
return 0;
}
static int tegra_xusb_phy_exit(struct phy *phy)
{
struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
return tegra_xusb_padctl_disable(padctl);
tegra_xusb_padctl_disable(padctl);
return 0;
}
static int pcie_phy_power_on(struct phy *phy)

View file

@ -43,7 +43,6 @@ struct dev_pin_info {
#endif
};
extern int pinctrl_bind_pins(struct device *dev);
extern int pinctrl_init_done(struct device *dev);
static inline struct pinctrl *dev_pinctrl(struct device *dev)
@ -58,11 +57,6 @@ static inline struct pinctrl *dev_pinctrl(struct device *dev)
/* Stubs if we're not using pinctrl */
static inline int pinctrl_bind_pins(struct device *dev)
{
return 0;
}
static inline int pinctrl_init_done(struct device *dev)
{
return 0;

View file

@ -250,9 +250,4 @@ static inline int pinconf_generic_dt_node_to_map_all(struct pinctrl_dev *pctldev
return pinconf_generic_dt_node_to_map(pctldev, np_config, map, num_maps,
PIN_MAP_TYPE_INVALID);
}
int pinconf_generic_dt_node_to_map_pinmux(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map,
unsigned int *num_maps);
#endif /* __LINUX_PINCTRL_PINCONF_GENERIC_H */

View file

@ -187,9 +187,6 @@ extern struct pinctrl_dev *devm_pinctrl_register(struct device *dev,
const struct pinctrl_desc *pctldesc,
void *driver_data);
extern void devm_pinctrl_unregister(struct device *dev,
struct pinctrl_dev *pctldev);
extern void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range);
extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev,