Commit 2de68638 authored by Linus Torvalds's avatar Linus Torvalds

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

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

   - Use DEFINE_SHOW_STORE_ATTRIBUTE() in debugfs entries

  New drivers:

   - Qualcomm PMIH0108, PMD8028, PMXR2230 and PM6450 pin control support

  Improvements:

   - Serious cleanup of the recently merged aw9523 driver

   - Fix PIN_CONFIG_BIAS_DISABLE handling in pinctrl-single

   - A slew of device tree binding cleanups

   - Support a bus clock in the Samsung driver"

* tag 'pinctrl-v6.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (48 commits)
  pinctrl: bcm2835: Make pin freeing behavior configurable
  dt-bindings: pinctrl: qcom,pmic-gpio: Fix "comptaible" typo for PMIH0108
  pinctrl: qcom: pinctrl-sm7150: Fix sdc1 and ufs special pins regs
  dt-bindings: pinctrl: mediatek: mt7622: add "antsel" function
  dt-bindings: pinctrl: mediatek: mt7622: fix array properties
  pinctrl: samsung: drop redundant drvdata assignment
  pinctrl: samsung: support a bus clock
  dt-bindings: pinctrl: samsung: google,gs101-pinctrl needs a clock
  pinctrl: renesas: rzg2l: Limit 2.5V power supply to Ethernet interfaces
  pinctrl: renesas: r8a779h0: Add INTC-EX pins, groups, and function
  pinctrl: renesas: r8a779h0: Fix IRQ suffixes
  pinctrl: renesas: rzg2l: Remove extra space in function parameter
  dt-bindings: pinctrl: qcom,pmic-mpp: add support for PM8901
  pinctrl: pinconf-generic: print hex value
  pinctrl: realtek: fix module autoloading
  pinctrl: qcom: sm7150: fix module autoloading
  pinctrl: loongson2: fix module autoloading
  pinctrl: mediatek: fix module autoloading
  pinctrl: freescale: imx8ulp: fix module autoloading
  dt-bindings: pinctrl: qcom,pmic-gpio: Allow gpio-hog nodes
  ...
parents 568c98a0 83906257
......@@ -34,6 +34,9 @@ properties:
the amount of cells must be specified as 2. See the below mentioned gpio
binding representation for description of particular cells.
gpio-ranges:
maxItems: 1
interrupt-controller: true
interrupts:
......@@ -75,8 +78,8 @@ patternProperties:
function:
description:
A string containing the name of the function to mux to the group.
enum: [emmc, eth, i2c, i2s, ir, led, flash, pcie, pmic, pwm, sd,
spi, tdm, uart, watchdog, wifi]
enum: [antsel, emmc, eth, i2c, i2s, ir, led, flash, pcie, pmic, pwm,
sd, spi, tdm, uart, watchdog, wifi]
groups:
description:
......@@ -90,6 +93,20 @@ patternProperties:
- function
allOf:
- if:
properties:
function:
const: antsel
then:
properties:
groups:
items:
enum: [antsel0, antsel1, antsel2, antsel3, antsel4, antsel5,
antsel6, antsel7, antsel8, antsel9, antsel10,
antsel11, antsel12, antsel13, antsel14, antsel15,
antsel16, antsel17, antsel18, antsel19, antsel20,
antsel21, antsel22, antsel23, antsel24, antsel25,
antsel26, antsel27, antsel28, antsel29]
- if:
properties:
function:
......@@ -97,6 +114,7 @@ patternProperties:
then:
properties:
groups:
items:
enum: [emmc, emmc_rst]
- if:
properties:
......@@ -105,6 +123,7 @@ patternProperties:
then:
properties:
groups:
items:
enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio]
- if:
......@@ -123,6 +142,7 @@ patternProperties:
then:
properties:
groups:
items:
enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data,
i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws,
i2s1_out_data, i2s2_out_data, i2s3_out_data,
......@@ -159,6 +179,7 @@ patternProperties:
then:
properties:
groups:
items:
enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
pcie0_pad_perst, pcie1_pad_perst, pcie_pereset,
......@@ -178,6 +199,7 @@ patternProperties:
then:
properties:
groups:
items:
enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1,
pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0,
pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1,
......@@ -260,6 +282,7 @@ patternProperties:
pins:
description:
An array of strings. Each string contains the name of a pin.
items:
enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0,
RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS,
I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT,
......
......@@ -24,6 +24,7 @@ properties:
- qcom,pm6150-gpio
- qcom,pm6150l-gpio
- qcom,pm6350-gpio
- qcom,pm6450-gpio
- qcom,pm7250b-gpio
- qcom,pm7325-gpio
- qcom,pm7550ba-gpio
......@@ -56,10 +57,12 @@ properties:
- qcom,pma8084-gpio
- qcom,pmc8180-gpio
- qcom,pmc8180c-gpio
- qcom,pmd8028-gpio
- qcom,pmi632-gpio
- qcom,pmi8950-gpio
- qcom,pmi8994-gpio
- qcom,pmi8998-gpio
- qcom,pmih0108-gpio
- qcom,pmk8350-gpio
- qcom,pmk8550-gpio
- qcom,pmm8155au-gpio
......@@ -72,6 +75,7 @@ properties:
- qcom,pmx55-gpio
- qcom,pmx65-gpio
- qcom,pmx75-gpio
- qcom,pmxr2230-gpio
- enum:
- qcom,spmi-gpio
......@@ -141,6 +145,7 @@ allOf:
- qcom,pm8005-gpio
- qcom,pm8450-gpio
- qcom,pm8916-gpio
- qcom,pmd8028-gpio
- qcom,pmk8350-gpio
- qcom,pmr735a-gpio
- qcom,pmr735b-gpio
......@@ -198,6 +203,7 @@ allOf:
contains:
enum:
- qcom,pm6350-gpio
- qcom,pm6450-gpio
- qcom,pm8350c-gpio
then:
properties:
......@@ -261,6 +267,7 @@ allOf:
- qcom,pmc8180c-gpio
- qcom,pmp8074-gpio
- qcom,pms405-gpio
- qcom,pmxr2230-gpio
then:
properties:
gpio-line-names:
......@@ -300,6 +307,21 @@ allOf:
minItems: 1
maxItems: 7
- if:
properties:
compatible:
contains:
enum:
- qcom,pmih0108-gpio
then:
properties:
gpio-line-names:
minItems: 18
maxItems: 18
gpio-reserved-ranges:
minItems: 1
maxItems: 9
- if:
properties:
compatible:
......@@ -402,6 +424,10 @@ patternProperties:
$ref: "#/$defs/qcom-pmic-gpio-state"
additionalProperties: false
"-hog(-[0-9]+)?$":
required:
- gpio-hog
$defs:
qcom-pmic-gpio-state:
type: object
......@@ -417,6 +443,7 @@ $defs:
- gpio1-gpio10 for pm6150
- gpio1-gpio12 for pm6150l
- gpio1-gpio9 for pm6350
- gpio1-gpio9 for pm6450
- gpio1-gpio12 for pm7250b
- gpio1-gpio10 for pm7325
- gpio1-gpio8 for pm7550ba
......@@ -447,9 +474,11 @@ $defs:
- gpio1-gpio22 for pm8994
- gpio1-gpio26 for pm8998
- gpio1-gpio22 for pma8084
- gpio1-gpio4 for pmd8028
- gpio1-gpio8 for pmi632
- gpio1-gpio2 for pmi8950
- gpio1-gpio10 for pmi8994
- gpio1-gpio18 for pmih0108
- gpio1-gpio4 for pmk8350
- gpio1-gpio6 for pmk8550
- gpio1-gpio10 for pmm8155au
......@@ -464,6 +493,7 @@ $defs:
and gpio11)
- gpio1-gpio16 for pmx65
- gpio1-gpio16 for pmx75
- gpio1-gpio12 for pmxr2230
items:
pattern: "^gpio([0-9]+)$"
......@@ -545,6 +575,7 @@ $defs:
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
pm8921_gpio: gpio@150 {
......@@ -568,5 +599,12 @@ examples:
power-source = <PM8921_GPIO_S4>;
};
};
otg-hog {
gpio-hog;
gpios = <35 GPIO_ACTIVE_HIGH>;
output-high;
line-name = "otg-gpio";
};
};
...
......@@ -35,6 +35,7 @@ properties:
- qcom,pm8038-mpp
- qcom,pm8058-mpp
- qcom,pm8821-mpp
- qcom,pm8901-mpp
- qcom,pm8917-mpp
- qcom,pm8921-mpp
- const: qcom,ssbi-mpp
......
......@@ -72,40 +72,24 @@ $defs:
description:
Specify the alternative function to be configured for the specified
pins.
enum: [ gpio, atest_char, atest_char0, atest_char1, atest_char2,
atest_char3, atest_usb0, atest_usb00, atest_usb01, atest_usb02,
atest_usb03, audio_ref, cam_mclk, cci_async, cci_i2c,
cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4,
cmu_rng0, cmu_rng1, cmu_rng2, cmu_rng3, coex_uart1, cri_trng,
cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
dp0_hot, gcc_gp1, gcc_gp2, gcc_gp3, host2wlan_sol, ibi_i3c,
jitter_bist, mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2,
mdp_vsync3, mi2s0_data0, mi2s0_data1, mi2s0_sck, mi2s0_ws,
mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, mi2s_mclk0,
mi2s_mclk1, nav_gpio0, nav_gpio1, nav_gpio2, pcie0_clk,
phase_flag0, phase_flag1, phase_flag10, phase_flag11,
phase_flag12, phase_flag13, phase_flag14, phase_flag15,
phase_flag16, phase_flag17, phase_flag18, phase_flag19,
phase_flag2, phase_flag20, phase_flag21, phase_flag22,
phase_flag23, phase_flag24, phase_flag25, phase_flag26,
phase_flag27, phase_flag28, phase_flag29, phase_flag3,
phase_flag30, phase_flag31, phase_flag4, phase_flag5,
phase_flag6, phase_flag7, phase_flag8, phase_flag9,
pll_bist, pll_clk, prng_rosc0, prng_rosc1, prng_rosc2,
prng_rosc3, qdss_cti, qdss_gpio, qdss_gpio0, qdss_gpio1,
qdss_gpio10, qdss_gpio11, qdss_gpio12, qdss_gpio13, qdss_gpio14,
qdss_gpio15, qdss_gpio2, qdss_gpio3, qdss_gpio4, qdss_gpio5,
qdss_gpio6, qdss_gpio7, qdss_gpio8, qdss_gpio9, qlink0_enable,
qlink0_request, qlink0_wmss, qlink1_enable, qlink1_request,
qlink1_wmss, qlink2_enable, qlink2_request, qlink2_wmss,
qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, qup0_se5,
qup0_se6, qup0_se7, qup1_se0, qup1_se1, qup1_se2, qup1_se3,
qup1_se4, qup1_se5, qup1_se6, sd_write, tb_trig, tgu_ch0,
tgu_ch1, tgu_ch2, tgu_ch3, tmess_prng0, tmess_prng1,
tmess_prng2, tmess_prng3, tsense_pwm1, tsense_pwm2, uim0_clk,
uim0_data, uim0_present, uim0_reset, uim1_clk, uim1_data,
uim1_present, uim1_reset, usb0_hs, usb0_phy, vfr_0, vfr_1,
vsense_trigger ]
enum: [ gpio, atest_char, atest_usb0, audio_ref_clk, cam_mclk,
cci_async_in0, cci_i2c, cci, cmu_rng, coex_uart1_rx,
coex_uart1_tx, cri_trng, dbg_out_clk, ddr_bist,
ddr_pxi0_test, ddr_pxi1_test, gcc_gp1_clk, gcc_gp2_clk,
gcc_gp3_clk, host2wlan_sol, ibi_i3c_qup0, ibi_i3c_qup1,
jitter_bist_ref, mdp_vsync0_out, mdp_vsync1_out,
mdp_vsync2_out, mdp_vsync3_out, mdp_vsync, nav,
pcie0_clk_req, phase_flag, pll_bist_sync, pll_clk_aux,
prng_rosc, qdss_cti_trig0, qdss_cti_trig1, qdss_gpio,
qlink0_enable, qlink0_request, qlink0_wmss_reset,
qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4,
qup1_se0, qup1_se1, qup1_se2, qup1_se2_l2, qup1_se3,
qup1_se4, sd_write_protect, tb_trig_sdc1, tb_trig_sdc2,
tgu_ch0_trigout, tgu_ch1_trigout, tgu_ch2_trigout,
tgu_ch3_trigout, tmess_prng, tsense_pwm1_out,
tsense_pwm2_out, uim0, uim1, usb0_hs_ac, usb0_phy_ps,
vfr_0_mira, vfr_0_mirb, vfr_1, vsense_trigger_mirnat,
wlan1_adc_dtest0, wlan1_adc_dtest1 ]
required:
- pins
......
......@@ -73,6 +73,13 @@ properties:
minItems: 1
maxItems: 2
clocks:
maxItems: 1
clock-names:
items:
- const: pclk
wakeup-interrupt-controller:
$ref: samsung,pinctrl-wakeup-interrupt.yaml
......@@ -120,6 +127,20 @@ required:
allOf:
- $ref: pinctrl.yaml#
- if:
properties:
compatible:
contains:
const: google,gs101-pinctrl
then:
required:
- clocks
- clock-names
else:
properties:
clocks: false
clock-names: false
- if:
properties:
compatible:
......
......@@ -17702,7 +17702,6 @@ C: irc://irc.libera.chat/linux-exynos
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
F: Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml
F: drivers/pinctrl/samsung/
F: include/dt-bindings/pinctrl/samsung.h
PIN CONTROLLER - SINGLE
M: Tony Lindgren <tony@atomide.com>
......
......@@ -244,6 +244,10 @@ static const char * const irq_type_names[] = {
[IRQ_TYPE_LEVEL_LOW] = "level-low",
};
static bool persist_gpio_outputs;
module_param(persist_gpio_outputs, bool, 0644);
MODULE_PARM_DESC(persist_gpio_outputs, "Enable GPIO_OUT persistence when pin is freed");
static inline u32 bcm2835_gpio_rd(struct bcm2835_pinctrl *pc, unsigned reg)
{
return readl(pc->base + reg);
......@@ -926,6 +930,13 @@ static int bcm2835_pmx_free(struct pinctrl_dev *pctldev,
unsigned offset)
{
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
if (fsel == BCM2835_FSEL_GPIO_IN)
return 0;
if (persist_gpio_outputs && fsel == BCM2835_FSEL_GPIO_OUT)
return 0;
/* disable by setting to GPIO_IN */
bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
......@@ -970,10 +981,7 @@ static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
{
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
/* disable by setting to GPIO_IN */
bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
bcm2835_pmx_free(pctldev, offset);
}
static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
......@@ -1003,8 +1011,27 @@ static const struct pinmux_ops bcm2835_pmx_ops = {
static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long *config)
{
/* No way to read back config in HW */
enum pin_config_param param = pinconf_to_config_param(*config);
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, pin);
u32 val;
/* No way to read back bias config in HW */
switch (param) {
case PIN_CONFIG_OUTPUT:
if (fsel != BCM2835_FSEL_GPIO_OUT)
return -EINVAL;
val = bcm2835_gpio_get_bit(pc, GPLEV0, pin);
*config = pinconf_to_config_packed(param, val);
break;
default:
return -ENOTSUPP;
}
return 0;
}
static void bcm2835_pull_config_set(struct bcm2835_pinctrl *pc,
......@@ -1079,6 +1106,45 @@ static const struct pinconf_ops bcm2835_pinconf_ops = {
.pin_config_set = bcm2835_pinconf_set,
};
static int bcm2711_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config)
{
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
u32 offset, shift, val;
offset = PUD_2711_REG_OFFSET(pin);
shift = PUD_2711_REG_SHIFT(pin);
val = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (offset * 4));
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_NONE)
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_UP)
return -EINVAL;
*config = pinconf_to_config_packed(param, 50000);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_DOWN)
return -EINVAL;
*config = pinconf_to_config_packed(param, 50000);
break;
default:
return bcm2835_pinconf_get(pctldev, pin, config);
}
return 0;
}
static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc,
unsigned int pin, unsigned int arg)
{
......@@ -1146,7 +1212,7 @@ static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev,
static const struct pinconf_ops bcm2711_pinconf_ops = {
.is_generic = true,
.pin_config_get = bcm2835_pinconf_get,
.pin_config_get = bcm2711_pinconf_get,
.pin_config_set = bcm2711_pinconf_set,
};
......@@ -1361,6 +1427,9 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
goto out_remove;
}
dev_info(dev, "GPIO_OUT persistence: %s\n",
persist_gpio_outputs ? "yes" : "no");
return 0;
out_remove:
......
......@@ -252,6 +252,7 @@ static const struct of_device_id imx8ulp_pinctrl_of_match[] = {
{ .compatible = "fsl,imx8ulp-iomuxc1", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx8ulp_pinctrl_of_match);
static int imx8ulp_pinctrl_probe(struct platform_device *pdev)
{
......
......@@ -1086,6 +1086,7 @@ static const struct of_device_id mt6765_pinctrl_of_match[] = {
{ .compatible = "mediatek,mt6765-pinctrl", .data = &mt6765_data },
{ }
};
MODULE_DEVICE_TABLE(of, mt6765_pinctrl_of_match);
static struct platform_driver mt6765_pinctrl_driver = {
.driver = {
......
......@@ -762,6 +762,7 @@ static const struct of_device_id mt6779_pinctrl_of_match[] = {
{ .compatible = "mediatek,mt6779-pinctrl", .data = &mt6779_data },
{ }
};
MODULE_DEVICE_TABLE(of, mt6779_pinctrl_of_match);
static struct platform_driver mt6779_pinctrl_driver = {
.driver = {
......
......@@ -834,8 +834,6 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
int *funcsize, const char *name)
{
int i = 0;
if (*funcsize <= 0)
return -EOVERFLOW;
......@@ -847,7 +845,6 @@ static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
return -EEXIST;
}
funcs++;
i++;
}
/* append new unique function */
......
......@@ -88,7 +88,7 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
seq_puts(s, items[i].display);
/* Print unit if available */
if (items[i].has_arg) {
seq_printf(s, " (%u",
seq_printf(s, " (0x%x",
pinconf_to_config_argument(config));
if (items[i].format)
seq_printf(s, " %s)", items[i].format);
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Awinic AW9523B i2c pin controller driver
* Copyright (c) 2020, AngeloGioacchino Del Regno
* <angelogioacchino.delregno@somainline.org>
* Copyright (c) 2020, AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
*/
#include <linux/bitfield.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/mutex.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#define AW9523_MAX_FUNCS 2
#define AW9523_NUM_PORTS 2
#define AW9523_PINS_PER_PORT 8
......@@ -56,27 +57,13 @@
/*
* struct aw9523_irq - Interrupt controller structure
* @lock: mutex locking for the irq bus
* @irqchip: structure holding irqchip params
* @cached_gpio: stores the previous gpio status for bit comparison
*/
struct aw9523_irq {
struct mutex lock;
struct irq_chip *irqchip;
u16 cached_gpio;
};
/*
* struct aw9523_pinmux - Pin mux params
* @name: Name of the mux
* @grps: Groups of the mux
* @num_grps: Number of groups (sizeof array grps)
*/
struct aw9523_pinmux {
const char *name;
const char * const *grps;
const u8 num_grps;
};
/*
* struct aw9523 - Main driver structure
* @dev: device handle
......@@ -151,23 +138,16 @@ static const struct pinctrl_ops aw9523_pinctrl_ops = {
};
static const char * const gpio_pwm_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
"gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
"gpio12", "gpio13", "gpio14", "gpio15"
"gpio0", "gpio1", "gpio2", "gpio3", /* 0-3 */
"gpio4", "gpio5", "gpio6", "gpio7", /* 4-7 */
"gpio8", "gpio9", "gpio10", "gpio11", /* 8-11 */
"gpio12", "gpio13", "gpio14", "gpio15", /* 11-15 */
};
/* Warning: Do NOT reorder this array */
static const struct aw9523_pinmux aw9523_pmx[] = {
{
.name = "pwm",
.grps = gpio_pwm_groups,
.num_grps = ARRAY_SIZE(gpio_pwm_groups),
},
{
.name = "gpio",
.grps = gpio_pwm_groups,
.num_grps = ARRAY_SIZE(gpio_pwm_groups),
},
static const struct pinfunction aw9523_pmx[] = {
PINCTRL_PINFUNCTION("pwm", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)),
PINCTRL_PINFUNCTION("gpio", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)),
};
static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl)
......@@ -183,10 +163,10 @@ static const char *aw9523_pmx_get_fname(struct pinctrl_dev *pctl,
static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel,
const char * const **groups,
unsigned int * const num_groups)
unsigned int * const ngroups)
{
*groups = aw9523_pmx[sel].grps;
*num_groups = aw9523_pmx[sel].num_grps;
*groups = aw9523_pmx[sel].groups;
*ngroups = aw9523_pmx[sel].ngroups;
return 0;
}
......@@ -239,7 +219,7 @@ static int aw9523_pcfg_param_to_reg(enum pin_config_param pcp, int pin, u8 *r)
reg = AW9523_REG_OUT_STATE(pin);
break;
default:
return -EOPNOTSUPP;
return -ENOTSUPP;
}
*r = reg;
......@@ -290,7 +270,7 @@ static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
break;
default:
return -EOPNOTSUPP;
return -ENOTSUPP;
}
if (val < 1)
return -EINVAL;
......@@ -344,7 +324,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
/* Open-Drain is supported only on port 0 */
if (pin >= AW9523_PINS_PER_PORT) {
rc = -EOPNOTSUPP;
rc = -ENOTSUPP;
goto end;
}
mask = AW9523_GCR_GPOMD_MASK;
......@@ -361,7 +341,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
val = AW9523_GCR_GPOMD_MASK;
break;
default:
rc = -EOPNOTSUPP;
rc = -ENOTSUPP;
goto end;
}
......@@ -408,8 +388,8 @@ static int aw9523_get_pin_direction(struct regmap *regmap, u8 pin, u8 n)
*
* Return: Zero for success or negative number for error
*/
static int aw9523_get_port_state(struct regmap *regmap, u8 pin,
u8 regbit, unsigned int *state)
static int aw9523_get_port_state(struct regmap *regmap, u8 pin, u8 regbit,
unsigned int *state)
{
u8 reg;
int dir;
......@@ -447,12 +427,12 @@ static int aw9523_gpio_irq_type(struct irq_data *d, unsigned int type)
static void aw9523_irq_mask(struct irq_data *d)
{
struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
irq_hw_number_t hwirq = irqd_to_hwirq(d);
unsigned int n = hwirq % AW9523_PINS_PER_PORT;
regmap_update_bits(awi->regmap,
AW9523_REG_INTR_DIS(d->hwirq),
regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq),
BIT(n), BIT(n));
gpiochip_disable_irq(&awi->gpio, irqd_to_hwirq(d));
gpiochip_disable_irq(&awi->gpio, hwirq);
}
/*
......@@ -465,11 +445,11 @@ static void aw9523_irq_mask(struct irq_data *d)
static void aw9523_irq_unmask(struct irq_data *d)
{
struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
irq_hw_number_t hwirq = irqd_to_hwirq(d);
unsigned int n = hwirq % AW9523_PINS_PER_PORT;
gpiochip_enable_irq(&awi->gpio, irqd_to_hwirq(d));
regmap_update_bits(awi->regmap,
AW9523_REG_INTR_DIS(d->hwirq),
gpiochip_enable_irq(&awi->gpio, hwirq);
regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq),
BIT(n), 0);
}
......@@ -622,7 +602,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
mutex_lock(&awi->i2c_lock);
/* Port 0 (gpio 0-7) */
m = *mask & U8_MAX;
m = *mask;
if (m) {
ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
if (ret)
......@@ -631,7 +611,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
*bits = state;
/* Port 1 (gpio 8-15) */
m = (*mask >> 8) & U8_MAX;
m = *mask >> 8;
if (m) {
ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
&state, m);
......@@ -652,29 +632,26 @@ static void 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;
mask_lo = *mask & U8_MAX;
mask_hi = (*mask >> 8) & U8_MAX;
mutex_lock(&awi->i2c_lock);
if (mask_hi) {
reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
bits_hi = (*bits >> 8) & U8_MAX;
ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
if (ret) {
if (ret)
dev_warn(awi->dev, "Cannot write port1 out level\n");
goto out;
}
}
if (mask_lo) {
reg = AW9523_REG_OUT_STATE(0);
bits_lo = *bits & U8_MAX;
ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
if (ret)
dev_warn(awi->dev, "Cannot write port0 out level\n");
}
out:
mutex_unlock(&awi->i2c_lock);
}
......@@ -827,29 +804,21 @@ static int aw9523_init_irq(struct aw9523 *awi, int irq)
{
struct device *dev = awi->dev;
struct gpio_irq_chip *girq;
struct irq_chip *irqchip;
int ret;
if (!device_property_read_bool(dev, "interrupt-controller"))
return 0;
irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL);
if (!irqchip)
return -ENOMEM;
awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL);
if (!awi->irq)
return -ENOMEM;
awi->irq->irqchip = irqchip;
mutex_init(&awi->irq->lock);
ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
IRQF_ONESHOT, dev_name(dev), awi);
if (ret) {
dev_err(dev, "Failed to request irq %d\n", irq);
return ret;
}
if (ret)
return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);
girq = &awi->gpio.irq;
gpio_irq_chip_set_chip(girq, &aw9523_irq_chip);
......@@ -1015,8 +984,7 @@ static int aw9523_probe(struct i2c_client *client)
}
mutex_init(&awi->i2c_lock);
lockdep_set_subclass(&awi->i2c_lock,
i2c_adapter_depth(client->adapter));
lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter));
pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL);
if (!pdesc)
......@@ -1046,8 +1014,7 @@ static int aw9523_probe(struct i2c_client *client)
awi->pctl = devm_pinctrl_register(dev, pdesc, awi);
if (IS_ERR(awi->pctl)) {
ret = PTR_ERR(awi->pctl);
dev_err(dev, "Cannot register pinctrl: %d", ret);
ret = dev_err_probe(dev, PTR_ERR(awi->pctl), "Cannot register pinctrl");
goto err_disable_vregs;
}
......@@ -1067,10 +1034,6 @@ static int aw9523_probe(struct i2c_client *client)
static void aw9523_remove(struct i2c_client *client)
{
struct aw9523 *awi = i2c_get_clientdata(client);
int ret;
if (!awi)
return;
/*
* If the chip VIO is connected to a regulator that we can turn
......@@ -1082,10 +1045,8 @@ static void aw9523_remove(struct i2c_client *client)
regulator_disable(awi->vio_vreg);
} else {
mutex_lock(&awi->i2c_lock);
ret = aw9523_hw_init(awi);
aw9523_hw_init(awi);
mutex_unlock(&awi->i2c_lock);
if (ret)
return;
}
mutex_destroy(&awi->i2c_lock);
......
......@@ -286,6 +286,7 @@ static const struct of_device_id loongson2_pinctrl_dt_match[] = {
},
{ }
};
MODULE_DEVICE_TABLE(of, loongson2_pinctrl_dt_match);
static struct platform_driver loongson2_pinctrl_driver = {
.probe = loongson2_pinctrl_probe,
......
......@@ -88,7 +88,6 @@ struct max77620_pingroup {
struct max77620_pin_info {
enum max77620_pin_ppdrv drv_type;
int pull_config;
};
struct max77620_fps_config {
......@@ -104,7 +103,6 @@ struct max77620_pctrl_info {
struct device *dev;
struct pinctrl_dev *pctl;
struct regmap *rmap;
int pins_current_opt[MAX77620_GPIO_NR];
const struct max77620_pin_function *functions;
unsigned int num_functions;
const struct max77620_pingroup *pin_groups;
......
......@@ -81,8 +81,6 @@ struct pcs_conf_type {
* @name: pinctrl function name
* @vals: register and vals array
* @nvals: number of entries in vals array
* @pgnames: array of pingroup names the function uses
* @npgnames: number of pingroup names the function uses
* @conf: array of pin configurations
* @nconfs: number of pin configurations available
* @node: list node
......@@ -91,8 +89,6 @@ struct pcs_function {
const char *name;
struct pcs_func_vals *vals;
unsigned nvals;
const char **pgnames;
int npgnames;
struct pcs_conf_vals *conf;
int nconfs;
struct list_head node;
......@@ -554,21 +550,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
unsigned offset = 0, shift = 0, i, data, ret;
u32 arg;
int j;
enum pin_config_param param;
ret = pcs_get_function(pctldev, pin, &func);
if (ret)
return ret;
for (j = 0; j < num_configs; j++) {
param = pinconf_to_config_param(configs[j]);
/* BIAS_DISABLE has no entry in the func->conf table */
if (param == PIN_CONFIG_BIAS_DISABLE) {
/* This just disables all bias entries */
pcs_pinconf_clear_bias(pctldev, pin);
continue;
}
for (i = 0; i < func->nconfs; i++) {
if (pinconf_to_config_param(configs[j])
!= func->conf[i].param)
if (param != func->conf[i].param)
continue;
offset = pin * (pcs->width / BITS_PER_BYTE);
data = pcs->read(pcs->base + offset);
arg = pinconf_to_config_argument(configs[j]);
switch (func->conf[i].param) {
switch (param) {
/* 2 parameters */
case PIN_CONFIG_INPUT_SCHMITT:
case PIN_CONFIG_DRIVE_STRENGTH:
......@@ -580,9 +585,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
data |= (arg << shift) & func->conf[i].mask;
break;
/* 4 parameters */
case PIN_CONFIG_BIAS_DISABLE:
pcs_pinconf_clear_bias(pctldev, pin);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
case PIN_CONFIG_BIAS_PULL_UP:
if (arg)
......@@ -1625,7 +1627,6 @@ static int pcs_irq_init_chained_handler(struct pcs_device *pcs,
return 0;
}
#ifdef CONFIG_PM
static int pcs_save_context(struct pcs_device *pcs)
{
int i, mux_bytes;
......@@ -1690,14 +1691,9 @@ static void pcs_restore_context(struct pcs_device *pcs)
}
}
static int pinctrl_single_suspend(struct platform_device *pdev,
pm_message_t state)
static int pinctrl_single_suspend_noirq(struct device *dev)
{
struct pcs_device *pcs;
pcs = platform_get_drvdata(pdev);
if (!pcs)
return -EINVAL;
struct pcs_device *pcs = dev_get_drvdata(dev);
if (pcs->flags & PCS_CONTEXT_LOSS_OFF) {
int ret;
......@@ -1710,20 +1706,19 @@ static int pinctrl_single_suspend(struct platform_device *pdev,
return pinctrl_force_sleep(pcs->pctl);
}
static int pinctrl_single_resume(struct platform_device *pdev)
static int pinctrl_single_resume_noirq(struct device *dev)
{
struct pcs_device *pcs;
pcs = platform_get_drvdata(pdev);
if (!pcs)
return -EINVAL;
struct pcs_device *pcs = dev_get_drvdata(dev);
if (pcs->flags & PCS_CONTEXT_LOSS_OFF)
pcs_restore_context(pcs);
return pinctrl_force_default(pcs->pctl);
}
#endif
static DEFINE_NOIRQ_DEV_PM_OPS(pinctrl_single_pm_ops,
pinctrl_single_suspend_noirq,
pinctrl_single_resume_noirq);
/**
* pcs_quirk_missing_pinctrl_cells - handle legacy binding
......@@ -1986,11 +1981,8 @@ static struct platform_driver pcs_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = pcs_of_match,
.pm = pm_sleep_ptr(&pinctrl_single_pm_ops),
},
#ifdef CONFIG_PM
.suspend = pinctrl_single_suspend,
.resume = pinctrl_single_resume,
#endif
};
module_platform_driver(pcs_driver);
......
......@@ -578,6 +578,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
return 0;
}
DEFINE_SHOW_ATTRIBUTE(pinmux_functions);
static int pinmux_pins_show(struct seq_file *s, void *what)
{
......@@ -650,6 +651,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
return 0;
}
DEFINE_SHOW_ATTRIBUTE(pinmux_pins);
void pinmux_show_map(struct seq_file *s, const struct pinctrl_map *map)
{
......@@ -672,10 +674,12 @@ void pinmux_show_setting(struct seq_file *s,
setting->data.mux.func);
}
DEFINE_SHOW_ATTRIBUTE(pinmux_functions);
DEFINE_SHOW_ATTRIBUTE(pinmux_pins);
static int pinmux_select_show(struct seq_file *s, void *unused)
{
return -EPERM;
}
static ssize_t pinmux_select(struct file *file, const char __user *user_buf,
static ssize_t pinmux_select_write(struct file *file, const char __user *user_buf,
size_t len, loff_t *ppos)
{
struct seq_file *sfile = file->private_data;
......@@ -749,19 +753,7 @@ static ssize_t pinmux_select(struct file *file, const char __user *user_buf,
return ret;
}
static int pinmux_select_open(struct inode *inode, struct file *file)
{
return single_open(file, NULL, inode->i_private);
}
static const struct file_operations pinmux_select_ops = {
.owner = THIS_MODULE,
.open = pinmux_select_open,
.write = pinmux_select,
.llseek = no_llseek,
.release = single_release,
};
DEFINE_SHOW_STORE_ATTRIBUTE(pinmux_select);
void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev)
......@@ -771,7 +763,7 @@ void pinmux_init_device_debugfs(struct dentry *devroot,
debugfs_create_file("pinmux-pins", 0444,
devroot, pctldev, &pinmux_pins_fops);
debugfs_create_file("pinmux-select", 0200,
devroot, pctldev, &pinmux_select_ops);
devroot, pctldev, &pinmux_select_fops);
}
#endif /* CONFIG_DEBUG_FS */
......
......@@ -32,7 +32,7 @@ static const char *pxa2xx_pctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned tgroup)
{
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *group = pctl->groups + tgroup;
struct pingroup *group = pctl->groups + tgroup;
return group->name;
}
......@@ -43,10 +43,10 @@ static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
unsigned *num_pins)
{
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *group = pctl->groups + tgroup;
struct pingroup *group = pctl->groups + tgroup;
*pins = (unsigned *)&group->pin;
*num_pins = 1;
*pins = group->pins;
*num_pins = group->npins;
return 0;
}
......@@ -109,7 +109,7 @@ static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev,
unsigned function)
{
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_function *pf = pctl->functions + function;
struct pinfunction *pf = pctl->functions + function;
return pf->name;
}
......@@ -127,7 +127,7 @@ static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev,
unsigned * const num_groups)
{
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_function *pf = pctl->functions + function;
struct pinfunction *pf = pctl->functions + function;
*groups = pf->groups;
*num_groups = pf->ngroups;
......@@ -139,20 +139,18 @@ static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function,
unsigned tgroup)
{
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *group = pctl->groups + tgroup;
struct pingroup *g = pctl->groups + tgroup;
unsigned int pin = g->pins[0];
struct pxa_desc_function *df;
int pin, shift;
unsigned long flags;
void __iomem *gafr, *gpdr;
int shift;
u32 val;
df = pxa_desc_by_func_group(pctl, group->name,
(pctl->functions + function)->name);
df = pxa_desc_by_func_group(pctl, g->name, (pctl->functions + function)->name);
if (!df)
return -EINVAL;
pin = group->pin;
gafr = pctl->base_gafr[pin / 16];
gpdr = pctl->base_gpdr[pin / 32];
shift = (pin % 16) << 1;
......@@ -186,9 +184,9 @@ static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev,
unsigned long *config)
{
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *g = pctl->groups + group;
struct pingroup *g = pctl->groups + group;
unsigned int pin = g->pins[0];
unsigned long flags;
unsigned pin = g->pin;
void __iomem *pgsr = pctl->base_pgsr[pin / 32];
u32 val;
......@@ -208,9 +206,9 @@ static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev,
unsigned num_configs)
{
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *g = pctl->groups + group;
struct pingroup *g = pctl->groups + group;
unsigned int pin = g->pins[0];
unsigned long flags;
unsigned pin = g->pin;
void __iomem *pgsr = pctl->base_pgsr[pin / 32];
int i, is_set = 0;
u32 val;
......@@ -249,11 +247,11 @@ static struct pinctrl_desc pxa2xx_pinctrl_desc = {
.pmxops = &pxa2xx_pinmux_ops,
};
static const struct pxa_pinctrl_function *
pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname,
const struct pxa_pinctrl_function *functions)
static const struct pinfunction *pxa2xx_find_function(struct pxa_pinctrl *pctl,
const char *fname,
const struct pinfunction *functions)
{
const struct pxa_pinctrl_function *func;
const struct pinfunction *func;
for (func = functions; func->name; func++)
if (!strcmp(fname, func->name))
......@@ -264,8 +262,8 @@ pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname,
static int pxa2xx_build_functions(struct pxa_pinctrl *pctl)
{
struct pinfunction *functions;
int i;
struct pxa_pinctrl_function *functions;
struct pxa_desc_function *df;
/*
......@@ -296,9 +294,9 @@ static int pxa2xx_build_functions(struct pxa_pinctrl *pctl)
static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
{
int i, j, ngroups;
struct pxa_pinctrl_function *func;
struct pxa_desc_function *df;
char **gtmp;
struct pinfunction *func;
const char **gtmp;
gtmp = devm_kmalloc_array(pctl->dev, pctl->npins, sizeof(*gtmp),
GFP_KERNEL);
......@@ -316,13 +314,9 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
pctl->ppins[j].pin.name;
func = pctl->functions + i;
func->ngroups = ngroups;
func->groups =
devm_kmalloc_array(pctl->dev, ngroups,
sizeof(char *), GFP_KERNEL);
func->groups = devm_kmemdup(pctl->dev, gtmp, ngroups * sizeof(*gtmp), GFP_KERNEL);
if (!func->groups)
return -ENOMEM;
memcpy(func->groups, gtmp, ngroups * sizeof(*gtmp));
}
devm_kfree(pctl->dev, gtmp);
......@@ -332,8 +326,8 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
static int pxa2xx_build_state(struct pxa_pinctrl *pctl,
const struct pxa_desc_pin *ppins, int npins)
{
struct pxa_pinctrl_group *group;
struct pinctrl_pin_desc *pins;
struct pingroup *group;
int ret, i;
pctl->npins = npins;
......@@ -357,7 +351,8 @@ static int pxa2xx_build_state(struct pxa_pinctrl *pctl,
for (i = 0; i < npins; i++) {
group = pctl->groups + i;
group->name = ppins[i].pin.name;
group->pin = ppins[i].pin.number;
group->pins = &ppins[i].pin.number;
group->npins = 1;
}
ret = pxa2xx_build_functions(pctl);
......
......@@ -52,17 +52,6 @@ struct pxa_desc_pin {
struct pxa_desc_function *functions;
};
struct pxa_pinctrl_group {
const char *name;
unsigned pin;
};
struct pxa_pinctrl_function {
const char *name;
const char **groups;
unsigned ngroups;
};
struct pxa_pinctrl {
spinlock_t lock;
void __iomem **base_gafr;
......@@ -74,9 +63,9 @@ struct pxa_pinctrl {
unsigned npins;
const struct pxa_desc_pin *ppins;
unsigned ngroups;
struct pxa_pinctrl_group *groups;
struct pingroup *groups;
unsigned nfuncs;
struct pxa_pinctrl_function *functions;
struct pinfunction *functions;
char *name;
};
......
......@@ -65,7 +65,7 @@ enum {
.intr_detection_width = 2, \
}
#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
#define SDC_QDSD_PINGROUP(pg_name, _tile, ctl, pull, drv) \
{ \
.grp = PINCTRL_PINGROUP(#pg_name, \
pg_name##_pins, \
......@@ -75,7 +75,7 @@ enum {
.intr_cfg_reg = 0, \
.intr_status_reg = 0, \
.intr_target_reg = 0, \
.tile = SOUTH, \
.tile = _tile, \
.mux_bit = -1, \
.pull_bit = pull, \
.drv_bit = drv, \
......@@ -101,7 +101,7 @@ enum {
.intr_cfg_reg = 0, \
.intr_status_reg = 0, \
.intr_target_reg = 0, \
.tile = SOUTH, \
.tile = WEST, \
.mux_bit = -1, \
.pull_bit = 3, \
.drv_bit = 0, \
......@@ -1199,13 +1199,13 @@ static const struct msm_pingroup sm7150_groups[] = {
[117] = PINGROUP(117, NORTH, _, _, _, _, _, _, _, _, _),
[118] = PINGROUP(118, NORTH, _, _, _, _, _, _, _, _, _),
[119] = UFS_RESET(ufs_reset, 0x9f000),
[120] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x9a000, 15, 0),
[121] = SDC_QDSD_PINGROUP(sdc1_clk, 0x9a000, 13, 6),
[122] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x9a000, 11, 3),
[123] = SDC_QDSD_PINGROUP(sdc1_data, 0x9a000, 9, 0),
[124] = SDC_QDSD_PINGROUP(sdc2_clk, 0x98000, 14, 6),
[125] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x98000, 11, 3),
[126] = SDC_QDSD_PINGROUP(sdc2_data, 0x98000, 9, 0),
[120] = SDC_QDSD_PINGROUP(sdc1_rclk, WEST, 0x9a000, 15, 0),
[121] = SDC_QDSD_PINGROUP(sdc1_clk, WEST, 0x9a000, 13, 6),
[122] = SDC_QDSD_PINGROUP(sdc1_cmd, WEST, 0x9a000, 11, 3),
[123] = SDC_QDSD_PINGROUP(sdc1_data, WEST, 0x9a000, 9, 0),
[124] = SDC_QDSD_PINGROUP(sdc2_clk, SOUTH, 0x98000, 14, 6),
[125] = SDC_QDSD_PINGROUP(sdc2_cmd, SOUTH, 0x98000, 11, 3),
[126] = SDC_QDSD_PINGROUP(sdc2_data, SOUTH, 0x98000, 9, 0),
};
static const struct msm_gpio_wakeirq_map sm7150_pdc_map[] = {
......@@ -1246,6 +1246,7 @@ static const struct of_device_id sm7150_tlmm_of_match[] = {
{ .compatible = "qcom,sm7150-tlmm", },
{ },
};
MODULE_DEVICE_TABLE(of, sm7150_tlmm_of_match);
static struct platform_driver sm7150_tlmm_driver = {
.driver = {
......
......@@ -1202,6 +1202,7 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm6150-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 },
{ .compatible = "qcom,pm6350-gpio", .data = (void *) 9 },
{ .compatible = "qcom,pm6450-gpio", .data = (void *) 9 },
{ .compatible = "qcom,pm7250b-gpio", .data = (void *) 12 },
{ .compatible = "qcom,pm7325-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pm7550ba-gpio", .data = (void *) 8},
......@@ -1234,10 +1235,12 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm8994-gpio", .data = (void *) 22 },
{ .compatible = "qcom,pm8998-gpio", .data = (void *) 26 },
{ .compatible = "qcom,pma8084-gpio", .data = (void *) 22 },
{ .compatible = "qcom,pmd8028-gpio", .data = (void *) 4 },
{ .compatible = "qcom,pmi632-gpio", .data = (void *) 8 },
{ .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 },
{ .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 },
{ .compatible = "qcom,pmih0108-gpio", .data = (void *) 18 },
{ .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 },
{ .compatible = "qcom,pmk8550-gpio", .data = (void *) 6 },
{ .compatible = "qcom,pmm8155au-gpio", .data = (void *) 10 },
......@@ -1253,6 +1256,7 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pmx55-gpio", .data = (void *) 11 },
{ .compatible = "qcom,pmx65-gpio", .data = (void *) 16 },
{ .compatible = "qcom,pmx75-gpio", .data = (void *) 16 },
{ .compatible = "qcom,pmxr2230-gpio", .data = (void *) 12 },
{ },
};
......
......@@ -1414,6 +1414,7 @@ static const struct of_device_id rtd1315e_pinctrl_of_match[] = {
{ .compatible = "realtek,rtd1315e-pinctrl", },
{},
};
MODULE_DEVICE_TABLE(of, rtd1315e_pinctrl_of_match);
static struct platform_driver rtd1315e_pinctrl_driver = {
.driver = {
......
......@@ -1584,6 +1584,7 @@ static const struct of_device_id rtd1319d_pinctrl_of_match[] = {
{ .compatible = "realtek,rtd1319d-pinctrl", },
{},
};
MODULE_DEVICE_TABLE(of, rtd1319d_pinctrl_of_match);
static struct platform_driver rtd1319d_pinctrl_driver = {
.driver = {
......
......@@ -75,10 +75,10 @@
#define GPSR0_9 F_(MSIOF5_SYNC, IP1SR0_7_4)
#define GPSR0_8 F_(MSIOF5_SS1, IP1SR0_3_0)
#define GPSR0_7 F_(MSIOF5_SS2, IP0SR0_31_28)
#define GPSR0_6 F_(IRQ0, IP0SR0_27_24)
#define GPSR0_5 F_(IRQ1, IP0SR0_23_20)
#define GPSR0_4 F_(IRQ2, IP0SR0_19_16)
#define GPSR0_3 F_(IRQ3, IP0SR0_15_12)
#define GPSR0_6 F_(IRQ0_A, IP0SR0_27_24)
#define GPSR0_5 F_(IRQ1_A, IP0SR0_23_20)
#define GPSR0_4 F_(IRQ2_A, IP0SR0_19_16)
#define GPSR0_3 F_(IRQ3_A, IP0SR0_15_12)
#define GPSR0_2 F_(GP0_02, IP0SR0_11_8)
#define GPSR0_1 F_(GP0_01, IP0SR0_7_4)
#define GPSR0_0 F_(GP0_00, IP0SR0_3_0)
......@@ -265,10 +265,10 @@
#define IP0SR0_3_0 F_(0, 0) FM(ERROROUTC_N_B) FM(TCLK2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_7_4 F_(0, 0) FM(MSIOF3_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_11_8 F_(0, 0) FM(MSIOF3_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_15_12 FM(IRQ3) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_19_16 FM(IRQ2) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_23_20 FM(IRQ1) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_27_24 FM(IRQ0) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_15_12 FM(IRQ3_A) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_19_16 FM(IRQ2_A) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_23_20 FM(IRQ1_A) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_27_24 FM(IRQ0_A) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_31_28 FM(MSIOF5_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
/* IP1SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
......@@ -672,16 +672,16 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_GPSR(IP0SR0_11_8, MSIOF3_SS2),
PINMUX_IPSR_GPSR(IP0SR0_15_12, IRQ3),
PINMUX_IPSR_GPSR(IP0SR0_15_12, IRQ3_A),
PINMUX_IPSR_GPSR(IP0SR0_15_12, MSIOF3_SCK),
PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2),
PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2_A),
PINMUX_IPSR_GPSR(IP0SR0_19_16, MSIOF3_TXD),
PINMUX_IPSR_GPSR(IP0SR0_23_20, IRQ1),
PINMUX_IPSR_GPSR(IP0SR0_23_20, IRQ1_A),
PINMUX_IPSR_GPSR(IP0SR0_23_20, MSIOF3_RXD),
PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0),
PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0_A),
PINMUX_IPSR_GPSR(IP0SR0_27_24, MSIOF3_SYNC),
PINMUX_IPSR_GPSR(IP0SR0_31_28, MSIOF5_SS2),
......@@ -1660,6 +1660,90 @@ static const unsigned int i2c3_mux[] = {
SDA3_MARK, SCL3_MARK,
};
/* - INTC-EX ---------------------------------------------------------------- */
static const unsigned int intc_ex_irq0_a_pins[] = {
/* IRQ0_A */
RCAR_GP_PIN(0, 6),
};
static const unsigned int intc_ex_irq0_a_mux[] = {
IRQ0_A_MARK,
};
static const unsigned int intc_ex_irq0_b_pins[] = {
/* IRQ0_B */
RCAR_GP_PIN(1, 20),
};
static const unsigned int intc_ex_irq0_b_mux[] = {
IRQ0_B_MARK,
};
static const unsigned int intc_ex_irq1_a_pins[] = {
/* IRQ1_A */
RCAR_GP_PIN(0, 5),
};
static const unsigned int intc_ex_irq1_a_mux[] = {
IRQ1_A_MARK,
};
static const unsigned int intc_ex_irq1_b_pins[] = {
/* IRQ1_B */
RCAR_GP_PIN(1, 21),
};
static const unsigned int intc_ex_irq1_b_mux[] = {
IRQ1_B_MARK,
};
static const unsigned int intc_ex_irq2_a_pins[] = {
/* IRQ2_A */
RCAR_GP_PIN(0, 4),
};
static const unsigned int intc_ex_irq2_a_mux[] = {
IRQ2_A_MARK,
};
static const unsigned int intc_ex_irq2_b_pins[] = {
/* IRQ2_B */
RCAR_GP_PIN(0, 13),
};
static const unsigned int intc_ex_irq2_b_mux[] = {
IRQ2_B_MARK,
};
static const unsigned int intc_ex_irq3_a_pins[] = {
/* IRQ3_A */
RCAR_GP_PIN(0, 3),
};
static const unsigned int intc_ex_irq3_a_mux[] = {
IRQ3_A_MARK,
};
static const unsigned int intc_ex_irq3_b_pins[] = {
/* IRQ3_B */
RCAR_GP_PIN(1, 23),
};
static const unsigned int intc_ex_irq3_b_mux[] = {
IRQ3_B_MARK,
};
static const unsigned int intc_ex_irq4_a_pins[] = {
/* IRQ4_A */
RCAR_GP_PIN(1, 17),
};
static const unsigned int intc_ex_irq4_a_mux[] = {
IRQ4_A_MARK,
};
static const unsigned int intc_ex_irq4_b_pins[] = {
/* IRQ4_B */
RCAR_GP_PIN(2, 3),
};
static const unsigned int intc_ex_irq4_b_mux[] = {
IRQ4_B_MARK,
};
static const unsigned int intc_ex_irq5_pins[] = {
/* IRQ5 */
RCAR_GP_PIN(2, 2),
};
static const unsigned int intc_ex_irq5_mux[] = {
IRQ5_MARK,
};
/* - MMC -------------------------------------------------------------------- */
static const unsigned int mmc_data_pins[] = {
/* MMC_SD_D[0:3], MMC_D[4:7] */
......@@ -2416,6 +2500,18 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(i2c2),
SH_PFC_PIN_GROUP(i2c3),
SH_PFC_PIN_GROUP(intc_ex_irq0_a),
SH_PFC_PIN_GROUP(intc_ex_irq0_b),
SH_PFC_PIN_GROUP(intc_ex_irq1_a),
SH_PFC_PIN_GROUP(intc_ex_irq1_b),
SH_PFC_PIN_GROUP(intc_ex_irq2_a),
SH_PFC_PIN_GROUP(intc_ex_irq2_b),
SH_PFC_PIN_GROUP(intc_ex_irq3_a),
SH_PFC_PIN_GROUP(intc_ex_irq3_b),
SH_PFC_PIN_GROUP(intc_ex_irq4_a),
SH_PFC_PIN_GROUP(intc_ex_irq4_b),
SH_PFC_PIN_GROUP(intc_ex_irq5),
BUS_DATA_PIN_GROUP(mmc_data, 1),
BUS_DATA_PIN_GROUP(mmc_data, 4),
BUS_DATA_PIN_GROUP(mmc_data, 8),
......@@ -2629,6 +2725,20 @@ static const char * const i2c3_groups[] = {
"i2c3",
};
static const char * const intc_ex_groups[] = {
"intc_ex_irq0_a",
"intc_ex_irq0_b",
"intc_ex_irq1_a",
"intc_ex_irq1_b",
"intc_ex_irq2_a",
"intc_ex_irq2_b",
"intc_ex_irq3_a",
"intc_ex_irq3_b",
"intc_ex_irq4_a",
"intc_ex_irq4_b",
"intc_ex_irq5",
};
static const char * const mmc_groups[] = {
"mmc_data1",
"mmc_data4",
......@@ -2813,6 +2923,8 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(i2c2),
SH_PFC_FUNCTION(i2c3),
SH_PFC_FUNCTION(intc_ex),
SH_PFC_FUNCTION(mmc),
SH_PFC_FUNCTION(msiof0),
......
......@@ -892,6 +892,8 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps
val = PVDD_1800;
break;
case 2500:
if (!(caps & (PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1)))
return -EINVAL;
val = PVDD_2500;
break;
case 3300:
......
......@@ -13,6 +13,7 @@
// the Samsung pinctrl/gpiolib driver. It also includes the implementation of
// external gpio and wakeup interrupt support.
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
......@@ -61,6 +62,12 @@ static void exynos_irq_mask(struct irq_data *irqd)
else
reg_mask = our_chip->eint_mask + bank->eint_offset;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for masking IRQ\n");
return;
}
raw_spin_lock_irqsave(&bank->slock, flags);
mask = readl(bank->eint_base + reg_mask);
......@@ -68,6 +75,8 @@ static void exynos_irq_mask(struct irq_data *irqd)
writel(mask, bank->eint_base + reg_mask);
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->drvdata->pclk);
}
static void exynos_irq_ack(struct irq_data *irqd)
......@@ -82,7 +91,15 @@ static void exynos_irq_ack(struct irq_data *irqd)
else
reg_pend = our_chip->eint_pend + bank->eint_offset;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock to ack IRQ\n");
return;
}
writel(1 << irqd->hwirq, bank->eint_base + reg_pend);
clk_disable(bank->drvdata->pclk);
}
static void exynos_irq_unmask(struct irq_data *irqd)
......@@ -110,6 +127,12 @@ static void exynos_irq_unmask(struct irq_data *irqd)
else
reg_mask = our_chip->eint_mask + bank->eint_offset;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for unmasking IRQ\n");
return;
}
raw_spin_lock_irqsave(&bank->slock, flags);
mask = readl(bank->eint_base + reg_mask);
......@@ -117,6 +140,8 @@ static void exynos_irq_unmask(struct irq_data *irqd)
writel(mask, bank->eint_base + reg_mask);
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->drvdata->pclk);
}
static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
......@@ -127,6 +152,7 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
unsigned int con, trig_type;
unsigned long reg_con;
int ret;
switch (type) {
case IRQ_TYPE_EDGE_RISING:
......@@ -159,11 +185,20 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
else
reg_con = our_chip->eint_con + bank->eint_offset;
ret = clk_enable(bank->drvdata->pclk);
if (ret) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for configuring IRQ type\n");
return ret;
}
con = readl(bank->eint_base + reg_con);
con &= ~(EXYNOS_EINT_CON_MASK << shift);
con |= trig_type << shift;
writel(con, bank->eint_base + reg_con);
clk_disable(bank->drvdata->pclk);
return 0;
}
......@@ -200,6 +235,14 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
ret = clk_enable(bank->drvdata->pclk);
if (ret) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for configuring pin %s-%lu\n",
bank->name, irqd->hwirq);
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags);
con = readl(bank->pctl_base + reg_con);
......@@ -209,6 +252,8 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->drvdata->pclk);
return 0;
}
......@@ -223,6 +268,13 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for deconfiguring pin %s-%lu\n",
bank->name, irqd->hwirq);
return;
}
raw_spin_lock_irqsave(&bank->slock, flags);
con = readl(bank->pctl_base + reg_con);
......@@ -232,6 +284,8 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->drvdata->pclk);
gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq);
}
......@@ -281,10 +335,19 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
unsigned int svc, group, pin;
int ret;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for handling IRQ\n");
return IRQ_NONE;
}
if (bank->eint_con_offset)
svc = readl(bank->eint_base + EXYNOSAUTO_SVC_OFFSET);
else
svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET);
clk_disable(bank->drvdata->pclk);
group = EXYNOS_SVC_GROUP(svc);
pin = svc & EXYNOS_SVC_NUM_MASK;
......@@ -563,6 +626,20 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
chained_irq_enter(chip, desc);
/*
* just enable the clock once here, to avoid an enable/disable dance for
* each bank.
*/
if (eintd->nr_banks) {
struct samsung_pin_bank *b = eintd->banks[0];
if (clk_enable(b->drvdata->pclk)) {
dev_err(b->gpio_chip.parent,
"unable to enable clock for pending IRQs\n");
return;
}
}
for (i = 0; i < eintd->nr_banks; ++i) {
struct samsung_pin_bank *b = eintd->banks[i];
pend = readl(b->eint_base + b->irq_chip->eint_pend
......@@ -572,6 +649,9 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
}
if (eintd->nr_banks)
clk_disable(eintd->banks[0]->drvdata->pclk);
chained_irq_exit(chip, desc);
}
......@@ -695,6 +775,12 @@ static void exynos_pinctrl_suspend_bank(
struct exynos_eint_gpio_save *save = bank->soc_priv;
const void __iomem *regs = bank->eint_base;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for saving state\n");
return;
}
save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ bank->eint_offset);
save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
......@@ -704,6 +790,8 @@ static void exynos_pinctrl_suspend_bank(
save->eint_mask = readl(regs + bank->irq_chip->eint_mask
+ bank->eint_offset);
clk_disable(bank->drvdata->pclk);
pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
......@@ -716,9 +804,17 @@ static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drv
struct exynos_eint_gpio_save *save = bank->soc_priv;
const void __iomem *regs = bank->eint_base;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for saving state\n");
return;
}
save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset);
save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset);
clk_disable(bank->drvdata->pclk);
pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
}
......@@ -753,6 +849,12 @@ static void exynos_pinctrl_resume_bank(
struct exynos_eint_gpio_save *save = bank->soc_priv;
void __iomem *regs = bank->eint_base;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for restoring state\n");
return;
}
pr_debug("%s: con %#010x => %#010x\n", bank->name,
readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ bank->eint_offset), save->eint_con);
......@@ -774,6 +876,8 @@ static void exynos_pinctrl_resume_bank(
+ 2 * bank->eint_offset + 4);
writel(save->eint_mask, regs + bank->irq_chip->eint_mask
+ bank->eint_offset);
clk_disable(bank->drvdata->pclk);
}
static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvdata,
......@@ -782,6 +886,12 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd
struct exynos_eint_gpio_save *save = bank->soc_priv;
void __iomem *regs = bank->eint_base;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for restoring state\n");
return;
}
pr_debug("%s: con %#010x => %#010x\n", bank->name,
readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con);
pr_debug("%s: mask %#010x => %#010x\n", bank->name,
......@@ -789,6 +899,8 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd
writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset);
writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset);
clk_disable(bank->drvdata->pclk);
}
void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
......
......@@ -15,6 +15,7 @@
// but provides extensions to which platform specific implementation of the gpio
// and wakeup interrupts can be hooked to.
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/init.h>
......@@ -371,7 +372,7 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
}
/* enable or disable a pinmux function */
static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
static int samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group)
{
struct samsung_pinctrl_drv_data *drvdata;
......@@ -382,6 +383,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
unsigned long flags;
const struct samsung_pmx_func *func;
const struct samsung_pin_group *grp;
int ret;
drvdata = pinctrl_dev_get_drvdata(pctldev);
func = &drvdata->pmx_functions[selector];
......@@ -397,6 +399,12 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
reg += 4;
}
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(pctldev->dev, "failed to enable clock for setup\n");
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags);
data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
......@@ -405,6 +413,10 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
return 0;
}
/* enable a specified pinmux by writing to registers */
......@@ -412,8 +424,7 @@ static int samsung_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned selector,
unsigned group)
{
samsung_pinmux_setup(pctldev, selector, group);
return 0;
return samsung_pinmux_setup(pctldev, selector, group);
}
/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
......@@ -436,6 +447,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
u32 data, width, pin_offset, mask, shift;
u32 cfg_value, cfg_reg;
unsigned long flags;
int ret;
drvdata = pinctrl_dev_get_drvdata(pctldev);
pin_to_reg_bank(drvdata, pin, &reg_base, &pin_offset, &bank);
......@@ -447,6 +459,12 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
width = type->fld_width[cfg_type];
cfg_reg = type->reg_offset[cfg_type];
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev, "failed to enable clock\n");
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags);
mask = (1 << width) - 1;
......@@ -466,6 +484,8 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
return 0;
}
......@@ -555,11 +575,19 @@ static void samsung_gpio_set_value(struct gpio_chip *gc,
static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
{
struct samsung_pin_bank *bank = gpiochip_get_data(gc);
struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;
unsigned long flags;
if (clk_enable(drvdata->pclk)) {
dev_err(drvdata->dev, "failed to enable clock\n");
return;
}
raw_spin_lock_irqsave(&bank->slock, flags);
samsung_gpio_set_value(gc, offset, value);
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
}
/* gpiolib gpio_get callback function */
......@@ -569,12 +597,23 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
u32 data;
struct samsung_pin_bank *bank = gpiochip_get_data(gc);
const struct samsung_pin_bank_type *type = bank->type;
struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;
int ret;
reg = bank->pctl_base + bank->pctl_offset;
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev, "failed to enable clock\n");
return ret;
}
data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);
data >>= offset;
data &= 1;
clk_disable(drvdata->pclk);
return data;
}
......@@ -619,12 +658,22 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc,
static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{
struct samsung_pin_bank *bank = gpiochip_get_data(gc);
struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;
unsigned long flags;
int ret;
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev, "failed to enable clock\n");
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags);
ret = samsung_gpio_set_direction(gc, offset, true);
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
return ret;
}
......@@ -633,14 +682,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
int value)
{
struct samsung_pin_bank *bank = gpiochip_get_data(gc);
struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;
unsigned long flags;
int ret;
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev, "failed to enable clock\n");
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags);
samsung_gpio_set_value(gc, offset, value);
ret = samsung_gpio_set_direction(gc, offset, false);
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
return ret;
}
......@@ -1164,6 +1222,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
}
}
drvdata->pclk = devm_clk_get_optional_prepared(dev, "pclk");
if (IS_ERR(drvdata->pclk)) {
ret = PTR_ERR(drvdata->pclk);
goto err_put_banks;
}
ret = samsung_pinctrl_register(pdev, drvdata);
if (ret)
goto err_put_banks;
......@@ -1202,6 +1266,13 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);
int i;
i = clk_enable(drvdata->pclk);
if (i) {
dev_err(drvdata->dev,
"failed to enable clock for saving state\n");
return i;
}
for (i = 0; i < drvdata->nr_banks; i++) {
struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
const void __iomem *reg = bank->pctl_base + bank->pctl_offset;
......@@ -1231,6 +1302,8 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
}
}
clk_disable(drvdata->pclk);
if (drvdata->suspend)
drvdata->suspend(drvdata);
if (drvdata->retention_ctrl && drvdata->retention_ctrl->enable)
......@@ -1250,8 +1323,20 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
{
struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);
int ret;
int i;
/*
* enable clock before the callback, as we don't want to have to deal
* with callback cleanup on clock failures.
*/
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev,
"failed to enable clock for restoring state\n");
return ret;
}
if (drvdata->resume)
drvdata->resume(drvdata);
......@@ -1286,6 +1371,8 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
writel(bank->pm_save[type], reg + offs[type]);
}
clk_disable(drvdata->pclk);
if (drvdata->retention_ctrl && drvdata->retention_ctrl->disable)
drvdata->retention_ctrl->disable(drvdata);
......
......@@ -274,6 +274,7 @@ struct samsung_pin_ctrl {
* through samsung_pinctrl_drv_data, not samsung_pin_bank).
* @dev: device instance representing the controller.
* @irq: interrpt number used by the controller to notify gpio interrupts.
* @pclk: optional bus clock if required for accessing registers
* @ctrl: pin controller instance managed by the driver.
* @pctl: pin controller descriptor registered with the pinctrl subsystem.
* @pctl_dev: cookie representing pinctrl device instance.
......@@ -293,6 +294,7 @@ struct samsung_pinctrl_drv_data {
void __iomem *virt_base;
struct device *dev;
int irq;
struct clk *pclk;
struct pinctrl_desc pctl;
struct pinctrl_dev *pctl_dev;
......
......@@ -169,7 +169,6 @@ static struct platform_driver sun9i_a80_r_pinctrl_driver = {
.probe = sun9i_a80_r_pinctrl_probe,
.driver = {
.name = "sun9i-a80-r-pinctrl",
.owner = THIS_MODULE,
.of_match_table = sun9i_a80_r_pinctrl_match,
},
};
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Samsung's Exynos pinctrl bindings
*
* Copyright (c) 2016 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Author: Krzysztof Kozlowski <krzk@kernel.org>
*/
#ifndef __DT_BINDINGS_PINCTRL_SAMSUNG_H__
#define __DT_BINDINGS_PINCTRL_SAMSUNG_H__
/*
* These bindings are deprecated, because they do not match the actual
* concept of bindings but rather contain pure register values.
* Instead include the header in the DTS source directory.
*/
#warning "These bindings are deprecated. Instead use the header in the DTS source directory."
#define EXYNOS_PIN_PULL_NONE 0
#define EXYNOS_PIN_PULL_DOWN 1
#define EXYNOS_PIN_PULL_UP 3
#define S3C64XX_PIN_PULL_NONE 0
#define S3C64XX_PIN_PULL_DOWN 1
#define S3C64XX_PIN_PULL_UP 2
/* Pin function in power down mode */
#define EXYNOS_PIN_PDN_OUT0 0
#define EXYNOS_PIN_PDN_OUT1 1
#define EXYNOS_PIN_PDN_INPUT 2
#define EXYNOS_PIN_PDN_PREV 3
/* Drive strengths for Exynos3250, Exynos4 (all) and Exynos5250 */
#define EXYNOS4_PIN_DRV_LV1 0
#define EXYNOS4_PIN_DRV_LV2 2
#define EXYNOS4_PIN_DRV_LV3 1
#define EXYNOS4_PIN_DRV_LV4 3
/* Drive strengths for Exynos5260 */
#define EXYNOS5260_PIN_DRV_LV1 0
#define EXYNOS5260_PIN_DRV_LV2 1
#define EXYNOS5260_PIN_DRV_LV4 2
#define EXYNOS5260_PIN_DRV_LV6 3
/*
* Drive strengths for Exynos5410, Exynos542x, Exynos5800 and Exynos850 (except
* GPIO_HSI block)
*/
#define EXYNOS5420_PIN_DRV_LV1 0
#define EXYNOS5420_PIN_DRV_LV2 1
#define EXYNOS5420_PIN_DRV_LV3 2
#define EXYNOS5420_PIN_DRV_LV4 3
/* Drive strengths for Exynos5433 */
#define EXYNOS5433_PIN_DRV_FAST_SR1 0
#define EXYNOS5433_PIN_DRV_FAST_SR2 1
#define EXYNOS5433_PIN_DRV_FAST_SR3 2
#define EXYNOS5433_PIN_DRV_FAST_SR4 3
#define EXYNOS5433_PIN_DRV_FAST_SR5 4
#define EXYNOS5433_PIN_DRV_FAST_SR6 5
#define EXYNOS5433_PIN_DRV_SLOW_SR1 8
#define EXYNOS5433_PIN_DRV_SLOW_SR2 9
#define EXYNOS5433_PIN_DRV_SLOW_SR3 0xa
#define EXYNOS5433_PIN_DRV_SLOW_SR4 0xb
#define EXYNOS5433_PIN_DRV_SLOW_SR5 0xc
#define EXYNOS5433_PIN_DRV_SLOW_SR6 0xf
/* Drive strengths for Exynos850 GPIO_HSI block */
#define EXYNOS850_HSI_PIN_DRV_LV1 0 /* 1x */
#define EXYNOS850_HSI_PIN_DRV_LV1_5 1 /* 1.5x */
#define EXYNOS850_HSI_PIN_DRV_LV2 2 /* 2x */
#define EXYNOS850_HSI_PIN_DRV_LV2_5 3 /* 2.5x */
#define EXYNOS850_HSI_PIN_DRV_LV3 4 /* 3x */
#define EXYNOS850_HSI_PIN_DRV_LV4 5 /* 4x */
#define EXYNOS_PIN_FUNC_INPUT 0
#define EXYNOS_PIN_FUNC_OUTPUT 1
#define EXYNOS_PIN_FUNC_2 2
#define EXYNOS_PIN_FUNC_3 3
#define EXYNOS_PIN_FUNC_4 4
#define EXYNOS_PIN_FUNC_5 5
#define EXYNOS_PIN_FUNC_6 6
#define EXYNOS_PIN_FUNC_EINT 0xf
#define EXYNOS_PIN_FUNC_F EXYNOS_PIN_FUNC_EINT
/* Drive strengths for Exynos7 FSYS1 block */
#define EXYNOS7_FSYS1_PIN_DRV_LV1 0
#define EXYNOS7_FSYS1_PIN_DRV_LV2 4
#define EXYNOS7_FSYS1_PIN_DRV_LV3 2
#define EXYNOS7_FSYS1_PIN_DRV_LV4 6
#define EXYNOS7_FSYS1_PIN_DRV_LV5 1
#define EXYNOS7_FSYS1_PIN_DRV_LV6 5
#endif /* __DT_BINDINGS_PINCTRL_SAMSUNG_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment