2019-05-27 09:55:21 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2013-06-11 00:16:22 +04:00
/*
* Pinctrl driver for Rockchip SoCs
*
* Copyright ( c ) 2013 MundoReader S . L .
* Author : Heiko Stuebner < heiko @ sntech . de >
*
* With some ideas taken from pinctrl - samsung :
* Copyright ( c ) 2012 Samsung Electronics Co . , Ltd .
* http : //www.samsung.com
* Copyright ( c ) 2012 Linaro Ltd
2020-07-13 21:35:41 +03:00
* https : //www.linaro.org
2013-06-11 00:16:22 +04:00
*
* and pinctrl - at91 :
* Copyright ( C ) 2011 - 2012 Jean - Christophe PLAGNIOL - VILLARD < plagnioj @ jcrosoft . com >
*/
2016-08-24 00:19:42 +03:00
# include <linux/init.h>
2013-06-11 00:16:22 +04:00
# include <linux/platform_device.h>
# include <linux/io.h>
# include <linux/bitops.h>
2018-09-13 14:58:21 +03:00
# include <linux/gpio/driver.h>
2013-06-11 00:16:22 +04:00
# include <linux/of_address.h>
# include <linux/of_irq.h>
# include <linux/pinctrl/machine.h>
# include <linux/pinctrl/pinconf.h>
# include <linux/pinctrl/pinctrl.h>
# include <linux/pinctrl/pinmux.h>
# include <linux/pinctrl/pinconf-generic.h>
# include <linux/irqchip/chained_irq.h>
2013-07-23 15:34:20 +04:00
# include <linux/clk.h>
2014-05-05 15:58:20 +04:00
# include <linux/regmap.h>
2014-05-05 15:59:09 +04:00
# include <linux/mfd/syscon.h>
2013-06-11 00:16:22 +04:00
# include <dt-bindings/pinctrl/rockchip.h>
# include "core.h"
# include "pinconf.h"
/* GPIO control registers */
# define GPIO_SWPORT_DR 0x00
# define GPIO_SWPORT_DDR 0x04
# define GPIO_INTEN 0x30
# define GPIO_INTMASK 0x34
# define GPIO_INTTYPE_LEVEL 0x38
# define GPIO_INT_POLARITY 0x3c
# define GPIO_INT_STATUS 0x40
# define GPIO_INT_RAWSTATUS 0x44
# define GPIO_DEBOUNCE 0x48
# define GPIO_PORTS_EOI 0x4c
# define GPIO_EXT_PORT 0x50
# define GPIO_LS_SYNC 0x60
2013-10-16 03:07:20 +04:00
enum rockchip_pinctrl_type {
2018-05-14 14:59:51 +03:00
PX30 ,
2017-03-17 20:18:36 +03:00
RV1108 ,
2013-10-16 03:07:20 +04:00
RK2928 ,
RK3066B ,
2017-07-21 09:27:15 +03:00
RK3128 ,
2013-10-16 03:07:20 +04:00
RK3188 ,
2014-07-20 03:49:17 +04:00
RK3288 ,
2019-10-15 12:17:08 +03:00
RK3308 ,
2015-06-13 00:51:01 +03:00
RK3368 ,
2016-02-01 05:58:21 +03:00
RK3399 ,
2013-10-16 03:07:20 +04:00
} ;
2020-07-13 17:49:24 +03:00
/*
2014-06-16 03:36:05 +04:00
* Encode variants of iomux registers into a type variable
*/
# define IOMUX_GPIO_ONLY BIT(0)
2014-06-16 03:36:57 +04:00
# define IOMUX_WIDTH_4BIT BIT(1)
2014-06-16 03:37:23 +04:00
# define IOMUX_SOURCE_PMU BIT(2)
2014-06-16 03:37:49 +04:00
# define IOMUX_UNROUTED BIT(3)
2017-02-10 13:23:47 +03:00
# define IOMUX_WIDTH_3BIT BIT(4)
2019-10-15 12:17:08 +03:00
# define IOMUX_WIDTH_2BIT BIT(5)
2014-06-16 03:36:05 +04:00
/**
2020-07-13 17:49:24 +03:00
* struct rockchip_iomux
2014-06-16 03:36:05 +04:00
* @ type : iomux variant using IOMUX_ * constants
2014-06-16 03:36:33 +04:00
* @ offset : if initialized to - 1 it will be autocalculated , by specifying
* an initial offset value the relevant source offset can be reset
* to a new value for autocalculating the following iomux registers .
2014-06-16 03:36:05 +04:00
*/
struct rockchip_iomux {
int type ;
2014-06-16 03:36:33 +04:00
int offset ;
2013-10-16 03:07:49 +04:00
} ;
2020-07-13 17:49:24 +03:00
/*
2016-02-01 05:58:21 +03:00
* enum type index corresponding to rockchip_perpin_drv_list arrays index .
*/
enum rockchip_pin_drv_type {
DRV_TYPE_IO_DEFAULT = 0 ,
DRV_TYPE_IO_1V8_OR_3V0 ,
DRV_TYPE_IO_1V8_ONLY ,
DRV_TYPE_IO_1V8_3V0_AUTO ,
DRV_TYPE_IO_3V3_ONLY ,
DRV_TYPE_MAX
} ;
2020-07-13 17:49:24 +03:00
/*
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
* enum type index corresponding to rockchip_pull_list arrays index .
*/
enum rockchip_pin_pull_type {
PULL_TYPE_IO_DEFAULT = 0 ,
PULL_TYPE_IO_1V8_ONLY ,
PULL_TYPE_MAX
} ;
2016-02-01 05:58:21 +03:00
/**
2020-07-13 17:49:24 +03:00
* struct rockchip_drv
2016-02-01 05:58:21 +03:00
* @ drv_type : drive strength variant using rockchip_perpin_drv_type
* @ offset : if initialized to - 1 it will be autocalculated , by specifying
* an initial offset value the relevant source offset can be reset
* to a new value for autocalculating the following drive strength
* registers . if used chips own cal_drv func instead to calculate
* registers offset , the variant could be ignored .
*/
struct rockchip_drv {
enum rockchip_pin_drv_type drv_type ;
int offset ;
} ;
2013-06-11 00:16:22 +04:00
/**
2020-07-13 17:49:24 +03:00
* struct rockchip_pin_bank
2013-06-11 00:16:22 +04:00
* @ reg_base : register base of the gpio bank
2020-07-13 17:49:24 +03:00
* @ regmap_pull : optional separate register for additional pull settings
2013-06-11 00:16:22 +04:00
* @ clk : clock of the gpio bank
* @ irq : interrupt of the gpio bank
2015-01-26 19:24:03 +03:00
* @ saved_masks : Saved content of GPIO_INTEN at suspend time .
2013-06-11 00:16:22 +04:00
* @ pin_base : first pin number
* @ nr_pins : number of pins in this bank
* @ name : name of the bank
* @ bank_num : number of the bank , to account for holes
2014-06-16 03:36:05 +04:00
* @ iomux : array describing the 4 iomux sources of the bank
2016-02-01 05:58:21 +03:00
* @ drv : array describing the 4 drive strength sources of the bank
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
* @ pull_type : array describing the 4 pull type sources of the bank
2017-12-24 00:22:54 +03:00
* @ valid : is all necessary information present
2013-06-11 00:16:22 +04:00
* @ of_node : dt node of this bank
* @ drvdata : common pinctrl basedata
* @ domain : irqdomain of the gpio bank
* @ gpio_chip : gpiolib chip
* @ grange : gpio range
* @ slock : spinlock for the gpio bank
2020-07-13 17:49:24 +03:00
* @ toggle_edge_mode : bit mask to toggle ( falling / rising ) edge mode
* @ recalced_mask : bit mask to indicate a need to recalulate the mask
2017-05-26 10:20:20 +03:00
* @ route_mask : bits describing the routing pins of per bank
2013-06-11 00:16:22 +04:00
*/
struct rockchip_pin_bank {
void __iomem * reg_base ;
2014-05-05 15:58:20 +04:00
struct regmap * regmap_pull ;
2013-06-11 00:16:22 +04:00
struct clk * clk ;
int irq ;
2015-01-26 19:24:03 +03:00
u32 saved_masks ;
2013-06-11 00:16:22 +04:00
u32 pin_base ;
u8 nr_pins ;
char * name ;
u8 bank_num ;
2014-06-16 03:36:05 +04:00
struct rockchip_iomux iomux [ 4 ] ;
2016-02-01 05:58:21 +03:00
struct rockchip_drv drv [ 4 ] ;
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
enum rockchip_pin_pull_type pull_type [ 4 ] ;
2013-06-11 00:16:22 +04:00
bool valid ;
struct device_node * of_node ;
struct rockchip_pinctrl * drvdata ;
struct irq_domain * domain ;
struct gpio_chip gpio_chip ;
struct pinctrl_gpio_range grange ;
2017-03-23 13:59:29 +03:00
raw_spinlock_t slock ;
2013-10-16 03:09:08 +04:00
u32 toggle_edge_mode ;
2017-07-21 09:27:14 +03:00
u32 recalced_mask ;
2017-05-26 10:20:20 +03:00
u32 route_mask ;
2013-06-11 00:16:22 +04:00
} ;
# define PIN_BANK(id, pins, label) \
{ \
. bank_num = id , \
. nr_pins = pins , \
. name = label , \
2014-06-16 03:36:33 +04:00
. iomux = { \
{ . offset = - 1 } , \
{ . offset = - 1 } , \
{ . offset = - 1 } , \
{ . offset = - 1 } , \
} , \
2013-06-11 00:16:22 +04:00
}
2014-06-16 03:36:05 +04:00
# define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
{ \
. bank_num = id , \
. nr_pins = pins , \
. name = label , \
. iomux = { \
2014-06-16 03:36:33 +04:00
{ . type = iom0 , . offset = - 1 } , \
{ . type = iom1 , . offset = - 1 } , \
{ . type = iom2 , . offset = - 1 } , \
{ . type = iom3 , . offset = - 1 } , \
2014-06-16 03:36:05 +04:00
} , \
}
2016-02-01 05:58:21 +03:00
# define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
{ \
. bank_num = id , \
. nr_pins = pins , \
. name = label , \
. iomux = { \
{ . offset = - 1 } , \
{ . offset = - 1 } , \
{ . offset = - 1 } , \
{ . offset = - 1 } , \
} , \
. drv = { \
{ . drv_type = type0 , . offset = - 1 } , \
{ . drv_type = type1 , . offset = - 1 } , \
{ . drv_type = type2 , . offset = - 1 } , \
{ . drv_type = type3 , . offset = - 1 } , \
} , \
}
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
# define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \
drv2 , drv3 , pull0 , pull1 , \
pull2 , pull3 ) \
{ \
. bank_num = id , \
. nr_pins = pins , \
. name = label , \
. iomux = { \
{ . offset = - 1 } , \
{ . offset = - 1 } , \
{ . offset = - 1 } , \
{ . offset = - 1 } , \
} , \
. drv = { \
{ . drv_type = drv0 , . offset = - 1 } , \
{ . drv_type = drv1 , . offset = - 1 } , \
{ . drv_type = drv2 , . offset = - 1 } , \
{ . drv_type = drv3 , . offset = - 1 } , \
} , \
. pull_type [ 0 ] = pull0 , \
. pull_type [ 1 ] = pull1 , \
. pull_type [ 2 ] = pull2 , \
. pull_type [ 3 ] = pull3 , \
}
2016-02-01 05:58:21 +03:00
# define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \
iom2 , iom3 , drv0 , drv1 , drv2 , \
drv3 , offset0 , offset1 , \
offset2 , offset3 ) \
{ \
. bank_num = id , \
. nr_pins = pins , \
. name = label , \
. iomux = { \
{ . type = iom0 , . offset = - 1 } , \
{ . type = iom1 , . offset = - 1 } , \
{ . type = iom2 , . offset = - 1 } , \
{ . type = iom3 , . offset = - 1 } , \
} , \
. drv = { \
{ . drv_type = drv0 , . offset = offset0 } , \
{ . drv_type = drv1 , . offset = offset1 } , \
{ . drv_type = drv2 , . offset = offset2 } , \
{ . drv_type = drv3 , . offset = offset3 } , \
} , \
}
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
# define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins, \
label , iom0 , iom1 , iom2 , \
iom3 , drv0 , drv1 , drv2 , \
drv3 , offset0 , offset1 , \
offset2 , offset3 , pull0 , \
pull1 , pull2 , pull3 ) \
{ \
. bank_num = id , \
. nr_pins = pins , \
. name = label , \
. iomux = { \
{ . type = iom0 , . offset = - 1 } , \
{ . type = iom1 , . offset = - 1 } , \
{ . type = iom2 , . offset = - 1 } , \
{ . type = iom3 , . offset = - 1 } , \
} , \
. drv = { \
{ . drv_type = drv0 , . offset = offset0 } , \
{ . drv_type = drv1 , . offset = offset1 } , \
{ . drv_type = drv2 , . offset = offset2 } , \
{ . drv_type = drv3 , . offset = offset3 } , \
} , \
. pull_type [ 0 ] = pull0 , \
. pull_type [ 1 ] = pull1 , \
. pull_type [ 2 ] = pull2 , \
. pull_type [ 3 ] = pull3 , \
}
2017-07-21 09:27:14 +03:00
/**
* struct rockchip_mux_recalced_data : represent a pin iomux data .
* @ num : bank number .
* @ pin : pin number .
* @ bit : index at register .
* @ reg : register offset .
* @ mask : mask bit
*/
struct rockchip_mux_recalced_data {
u8 num ;
u8 pin ;
2017-08-23 11:00:07 +03:00
u32 reg ;
2017-07-21 09:27:14 +03:00
u8 bit ;
u8 mask ;
} ;
2018-11-12 00:00:46 +03:00
enum rockchip_mux_route_location {
ROCKCHIP_ROUTE_SAME = 0 ,
ROCKCHIP_ROUTE_PMU ,
ROCKCHIP_ROUTE_GRF ,
} ;
2017-05-26 10:20:20 +03:00
/**
* struct rockchip_mux_recalced_data : represent a pin iomux data .
* @ bank_num : bank number .
* @ pin : index at register or used to calc index .
* @ func : the min pin .
2020-07-13 17:49:24 +03:00
* @ route_location : the mux route location ( same , pmu , grf ) .
2017-05-26 10:20:20 +03:00
* @ route_offset : the max pin .
* @ route_val : the register offset .
*/
struct rockchip_mux_route_data {
u8 bank_num ;
u8 pin ;
u8 func ;
2018-11-12 00:00:46 +03:00
enum rockchip_mux_route_location route_location ;
2017-05-26 10:20:20 +03:00
u32 route_offset ;
u32 route_val ;
} ;
2013-06-11 00:16:22 +04:00
struct rockchip_pin_ctrl {
struct rockchip_pin_bank * pin_banks ;
u32 nr_banks ;
u32 nr_pins ;
char * label ;
2013-10-16 03:07:20 +04:00
enum rockchip_pinctrl_type type ;
2014-06-16 03:37:23 +04:00
int grf_mux_offset ;
int pmu_mux_offset ;
2016-02-01 05:58:21 +03:00
int grf_drv_offset ;
int pmu_drv_offset ;
2017-07-21 09:27:14 +03:00
struct rockchip_mux_recalced_data * iomux_recalced ;
u32 niomux_recalced ;
2017-05-26 10:20:20 +03:00
struct rockchip_mux_route_data * iomux_routes ;
u32 niomux_routes ;
2016-02-01 05:58:21 +03:00
2014-05-05 15:58:20 +04:00
void ( * pull_calc_reg ) ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit ) ;
2015-06-13 00:50:11 +03:00
void ( * drv_calc_reg ) ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit ) ;
2017-03-02 10:11:23 +03:00
int ( * schmitt_calc_reg ) ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit ) ;
2013-06-11 00:16:22 +04:00
} ;
struct rockchip_pin_config {
unsigned int func ;
unsigned long * configs ;
unsigned int nconfigs ;
} ;
/**
* struct rockchip_pin_group : represent group of pins of a pinmux function .
* @ name : name of the pin group , used to lookup the group .
* @ pins : the pins included in this group .
* @ npins : number of pins included in this group .
2020-07-13 17:49:24 +03:00
* @ data : local pin configuration
2013-06-11 00:16:22 +04:00
*/
struct rockchip_pin_group {
const char * name ;
unsigned int npins ;
unsigned int * pins ;
struct rockchip_pin_config * data ;
} ;
/**
* struct rockchip_pmx_func : represent a pin function .
* @ name : name of the pin function , used to lookup the function .
* @ groups : one or more names of pin groups that provide this function .
2020-07-13 17:49:24 +03:00
* @ ngroups : number of groups included in @ groups .
2013-06-11 00:16:22 +04:00
*/
struct rockchip_pmx_func {
const char * name ;
const char * * groups ;
u8 ngroups ;
} ;
struct rockchip_pinctrl {
2014-05-05 15:58:20 +04:00
struct regmap * regmap_base ;
2014-05-05 15:58:00 +04:00
int reg_size ;
2014-05-05 15:58:20 +04:00
struct regmap * regmap_pull ;
2014-05-05 15:59:09 +04:00
struct regmap * regmap_pmu ;
2013-06-11 00:16:22 +04:00
struct device * dev ;
struct rockchip_pin_ctrl * ctrl ;
struct pinctrl_desc pctl ;
struct pinctrl_dev * pctl_dev ;
struct rockchip_pin_group * groups ;
unsigned int ngroups ;
struct rockchip_pmx_func * functions ;
unsigned int nfunctions ;
} ;
2014-05-05 15:58:20 +04:00
static struct regmap_config rockchip_regmap_config = {
. reg_bits = 32 ,
. val_bits = 32 ,
. reg_stride = 4 ,
} ;
2016-06-13 18:18:34 +03:00
static inline const struct rockchip_pin_group * pinctrl_name_to_group (
2013-06-11 00:16:22 +04:00
const struct rockchip_pinctrl * info ,
const char * name )
{
int i ;
for ( i = 0 ; i < info - > ngroups ; i + + ) {
2013-08-21 06:28:50 +04:00
if ( ! strcmp ( info - > groups [ i ] . name , name ) )
return & info - > groups [ i ] ;
2013-06-11 00:16:22 +04:00
}
2013-08-21 06:28:50 +04:00
return NULL ;
2013-06-11 00:16:22 +04:00
}
/*
* given a pin number that is local to a pin controller , find out the pin bank
* and the register base of the pin bank .
*/
static struct rockchip_pin_bank * pin_to_bank ( struct rockchip_pinctrl * info ,
unsigned pin )
{
struct rockchip_pin_bank * b = info - > ctrl - > pin_banks ;
2013-08-23 11:49:00 +04:00
while ( pin > = ( b - > pin_base + b - > nr_pins ) )
2013-06-11 00:16:22 +04:00
b + + ;
return b ;
}
static struct rockchip_pin_bank * bank_num_to_bank (
struct rockchip_pinctrl * info ,
unsigned num )
{
struct rockchip_pin_bank * b = info - > ctrl - > pin_banks ;
int i ;
2013-08-21 06:28:50 +04:00
for ( i = 0 ; i < info - > ctrl - > nr_banks ; i + + , b + + ) {
2013-06-11 00:16:22 +04:00
if ( b - > bank_num = = num )
2013-08-21 06:28:50 +04:00
return b ;
2013-06-11 00:16:22 +04:00
}
2013-08-21 06:28:50 +04:00
return ERR_PTR ( - EINVAL ) ;
2013-06-11 00:16:22 +04:00
}
/*
* Pinctrl_ops handling
*/
static int rockchip_get_groups_count ( struct pinctrl_dev * pctldev )
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
return info - > ngroups ;
}
static const char * rockchip_get_group_name ( struct pinctrl_dev * pctldev ,
unsigned selector )
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
return info - > groups [ selector ] . name ;
}
static int rockchip_get_group_pins ( struct pinctrl_dev * pctldev ,
unsigned selector , const unsigned * * pins ,
unsigned * npins )
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
if ( selector > = info - > ngroups )
return - EINVAL ;
* pins = info - > groups [ selector ] . pins ;
* npins = info - > groups [ selector ] . npins ;
return 0 ;
}
static int rockchip_dt_node_to_map ( struct pinctrl_dev * pctldev ,
struct device_node * np ,
struct pinctrl_map * * map , unsigned * num_maps )
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
const struct rockchip_pin_group * grp ;
struct pinctrl_map * new_map ;
struct device_node * parent ;
int map_num = 1 ;
int i ;
/*
* first find the group of this node and check if we need to create
* config maps for pins
*/
grp = pinctrl_name_to_group ( info , np - > name ) ;
if ( ! grp ) {
2018-08-28 04:52:41 +03:00
dev_err ( info - > dev , " unable to find group for node %pOFn \n " ,
np ) ;
2013-06-11 00:16:22 +04:00
return - EINVAL ;
}
map_num + = grp - > npins ;
2020-05-06 13:09:03 +03:00
new_map = kcalloc ( map_num , sizeof ( * new_map ) , GFP_KERNEL ) ;
2013-06-11 00:16:22 +04:00
if ( ! new_map )
return - ENOMEM ;
* map = new_map ;
* num_maps = map_num ;
/* create mux map */
parent = of_get_parent ( np ) ;
if ( ! parent ) {
2020-05-06 13:09:03 +03:00
kfree ( new_map ) ;
2013-06-11 00:16:22 +04:00
return - EINVAL ;
}
new_map [ 0 ] . type = PIN_MAP_TYPE_MUX_GROUP ;
new_map [ 0 ] . data . mux . function = parent - > name ;
new_map [ 0 ] . data . mux . group = np - > name ;
of_node_put ( parent ) ;
/* create config map */
new_map + + ;
for ( i = 0 ; i < grp - > npins ; i + + ) {
new_map [ i ] . type = PIN_MAP_TYPE_CONFIGS_PIN ;
new_map [ i ] . data . configs . group_or_pin =
pin_get_name ( pctldev , grp - > pins [ i ] ) ;
new_map [ i ] . data . configs . configs = grp - > data [ i ] . configs ;
new_map [ i ] . data . configs . num_configs = grp - > data [ i ] . nconfigs ;
}
dev_dbg ( pctldev - > dev , " maps: function %s group %s num %d \n " ,
( * map ) - > data . mux . function , ( * map ) - > data . mux . group , map_num ) ;
return 0 ;
}
static void rockchip_dt_free_map ( struct pinctrl_dev * pctldev ,
struct pinctrl_map * map , unsigned num_maps )
{
2020-05-06 13:09:03 +03:00
kfree ( map ) ;
2013-06-11 00:16:22 +04:00
}
static const struct pinctrl_ops rockchip_pctrl_ops = {
. get_groups_count = rockchip_get_groups_count ,
. get_group_name = rockchip_get_group_name ,
. get_group_pins = rockchip_get_group_pins ,
. dt_node_to_map = rockchip_dt_node_to_map ,
. dt_free_map = rockchip_dt_free_map ,
} ;
/*
* Hardware access
*/
2017-08-23 11:00:07 +03:00
static struct rockchip_mux_recalced_data rv1108_mux_recalced_data [ ] = {
{
. num = 1 ,
. pin = 0 ,
. reg = 0x418 ,
. bit = 0 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 1 ,
. reg = 0x418 ,
. bit = 2 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 2 ,
. reg = 0x418 ,
. bit = 4 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 3 ,
. reg = 0x418 ,
. bit = 6 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 4 ,
. reg = 0x418 ,
. bit = 8 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 5 ,
. reg = 0x418 ,
. bit = 10 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 6 ,
. reg = 0x418 ,
. bit = 12 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 7 ,
. reg = 0x418 ,
. bit = 14 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 8 ,
. reg = 0x41c ,
. bit = 0 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 9 ,
. reg = 0x41c ,
. bit = 2 ,
. mask = 0x3
} ,
} ;
2017-07-21 09:27:15 +03:00
static struct rockchip_mux_recalced_data rk3128_mux_recalced_data [ ] = {
{
. num = 2 ,
. pin = 20 ,
. reg = 0xe8 ,
. bit = 0 ,
. mask = 0x7
} , {
. num = 2 ,
. pin = 21 ,
. reg = 0xe8 ,
. bit = 4 ,
. mask = 0x7
} , {
. num = 2 ,
. pin = 22 ,
. reg = 0xe8 ,
. bit = 8 ,
. mask = 0x7
} , {
. num = 2 ,
. pin = 23 ,
. reg = 0xe8 ,
. bit = 12 ,
. mask = 0x7
} , {
. num = 2 ,
. pin = 24 ,
. reg = 0xd4 ,
. bit = 12 ,
. mask = 0x7
} ,
} ;
2019-10-15 12:17:08 +03:00
static struct rockchip_mux_recalced_data rk3308_mux_recalced_data [ ] = {
{
. num = 1 ,
. pin = 14 ,
. reg = 0x28 ,
. bit = 12 ,
. mask = 0xf
} , {
. num = 1 ,
. pin = 15 ,
. reg = 0x2c ,
. bit = 0 ,
. mask = 0x3
} , {
. num = 1 ,
. pin = 18 ,
. reg = 0x30 ,
. bit = 4 ,
. mask = 0xf
} , {
. num = 1 ,
. pin = 19 ,
. reg = 0x30 ,
. bit = 8 ,
. mask = 0xf
} , {
. num = 1 ,
. pin = 20 ,
. reg = 0x30 ,
. bit = 12 ,
. mask = 0xf
} , {
. num = 1 ,
. pin = 21 ,
. reg = 0x34 ,
. bit = 0 ,
. mask = 0xf
} , {
. num = 1 ,
. pin = 22 ,
. reg = 0x34 ,
. bit = 4 ,
. mask = 0xf
} , {
. num = 1 ,
. pin = 23 ,
. reg = 0x34 ,
. bit = 8 ,
. mask = 0xf
} , {
. num = 3 ,
. pin = 12 ,
. reg = 0x68 ,
. bit = 8 ,
. mask = 0xf
} , {
. num = 3 ,
. pin = 13 ,
. reg = 0x68 ,
. bit = 12 ,
. mask = 0xf
} , {
. num = 2 ,
. pin = 2 ,
. reg = 0x608 ,
. bit = 0 ,
. mask = 0x7
} , {
. num = 2 ,
. pin = 3 ,
. reg = 0x608 ,
. bit = 4 ,
. mask = 0x7
} , {
. num = 2 ,
. pin = 16 ,
. reg = 0x610 ,
. bit = 8 ,
. mask = 0x7
} , {
. num = 3 ,
. pin = 10 ,
. reg = 0x610 ,
. bit = 0 ,
. mask = 0x7
} , {
. num = 3 ,
. pin = 11 ,
. reg = 0x610 ,
. bit = 4 ,
. mask = 0x7
} ,
} ;
2017-07-21 09:27:14 +03:00
static struct rockchip_mux_recalced_data rk3328_mux_recalced_data [ ] = {
2017-02-10 13:23:49 +03:00
{
. num = 2 ,
. pin = 12 ,
. reg = 0x24 ,
. bit = 8 ,
. mask = 0x3
} , {
. num = 2 ,
. pin = 15 ,
. reg = 0x28 ,
. bit = 0 ,
. mask = 0x7
} , {
. num = 2 ,
. pin = 23 ,
. reg = 0x30 ,
. bit = 14 ,
. mask = 0x3
} ,
} ;
2017-07-21 09:27:14 +03:00
static void rockchip_get_recalced_mux ( struct rockchip_pin_bank * bank , int pin ,
int * reg , u8 * bit , int * mask )
2017-02-10 13:23:49 +03:00
{
2017-07-21 09:27:14 +03:00
struct rockchip_pinctrl * info = bank - > drvdata ;
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
struct rockchip_mux_recalced_data * data ;
2017-02-10 13:23:49 +03:00
int i ;
2017-07-21 09:27:14 +03:00
for ( i = 0 ; i < ctrl - > niomux_recalced ; i + + ) {
data = & ctrl - > iomux_recalced [ i ] ;
if ( data - > num = = bank - > bank_num & &
data - > pin = = pin )
2017-02-10 13:23:49 +03:00
break ;
2017-07-21 09:27:14 +03:00
}
2017-02-10 13:23:49 +03:00
2017-07-21 09:27:14 +03:00
if ( i > = ctrl - > niomux_recalced )
2017-02-10 13:23:49 +03:00
return ;
* reg = data - > reg ;
* mask = data - > mask ;
* bit = data - > bit ;
}
2018-05-14 14:59:51 +03:00
static struct rockchip_mux_route_data px30_mux_route_data [ ] = {
{
/* cif-d2m0 */
. bank_num = 2 ,
. pin = 0 ,
. func = 1 ,
. route_offset = 0x184 ,
. route_val = BIT ( 16 + 7 ) ,
} , {
/* cif-d2m1 */
. bank_num = 3 ,
. pin = 3 ,
. func = 3 ,
. route_offset = 0x184 ,
. route_val = BIT ( 16 + 7 ) | BIT ( 7 ) ,
} , {
/* pdm-m0 */
. bank_num = 3 ,
. pin = 22 ,
. func = 2 ,
. route_offset = 0x184 ,
. route_val = BIT ( 16 + 8 ) ,
} , {
/* pdm-m1 */
. bank_num = 2 ,
. pin = 22 ,
. func = 1 ,
. route_offset = 0x184 ,
. route_val = BIT ( 16 + 8 ) | BIT ( 8 ) ,
} , {
/* uart2-rxm0 */
. bank_num = 1 ,
. pin = 27 ,
. func = 2 ,
. route_offset = 0x184 ,
. route_val = BIT ( 16 + 10 ) ,
} , {
/* uart2-rxm1 */
. bank_num = 2 ,
. pin = 14 ,
. func = 2 ,
. route_offset = 0x184 ,
. route_val = BIT ( 16 + 10 ) | BIT ( 10 ) ,
} , {
/* uart3-rxm0 */
. bank_num = 0 ,
. pin = 17 ,
. func = 2 ,
. route_offset = 0x184 ,
. route_val = BIT ( 16 + 9 ) ,
} , {
/* uart3-rxm1 */
. bank_num = 1 ,
. pin = 15 ,
. func = 2 ,
. route_offset = 0x184 ,
. route_val = BIT ( 16 + 9 ) | BIT ( 9 ) ,
} ,
} ;
2017-07-21 09:27:15 +03:00
static struct rockchip_mux_route_data rk3128_mux_route_data [ ] = {
{
/* spi-0 */
. bank_num = 1 ,
. pin = 10 ,
. func = 1 ,
. route_offset = 0x144 ,
. route_val = BIT ( 16 + 3 ) | BIT ( 16 + 4 ) ,
} , {
/* spi-1 */
. bank_num = 1 ,
. pin = 27 ,
. func = 3 ,
. route_offset = 0x144 ,
. route_val = BIT ( 16 + 3 ) | BIT ( 16 + 4 ) | BIT ( 3 ) ,
} , {
/* spi-2 */
. bank_num = 0 ,
. pin = 13 ,
. func = 2 ,
. route_offset = 0x144 ,
. route_val = BIT ( 16 + 3 ) | BIT ( 16 + 4 ) | BIT ( 4 ) ,
} , {
/* i2s-0 */
. bank_num = 1 ,
. pin = 5 ,
. func = 1 ,
. route_offset = 0x144 ,
. route_val = BIT ( 16 + 5 ) ,
} , {
/* i2s-1 */
. bank_num = 0 ,
. pin = 14 ,
. func = 1 ,
. route_offset = 0x144 ,
. route_val = BIT ( 16 + 5 ) | BIT ( 5 ) ,
} , {
/* emmc-0 */
. bank_num = 1 ,
. pin = 22 ,
. func = 2 ,
. route_offset = 0x144 ,
. route_val = BIT ( 16 + 6 ) ,
} , {
/* emmc-1 */
. bank_num = 2 ,
. pin = 4 ,
. func = 2 ,
. route_offset = 0x144 ,
. route_val = BIT ( 16 + 6 ) | BIT ( 6 ) ,
} ,
} ;
2018-11-12 00:00:47 +03:00
static struct rockchip_mux_route_data rk3188_mux_route_data [ ] = {
{
/* non-iomuxed emmc/flash pins on flash-dqs */
. bank_num = 0 ,
. pin = 24 ,
. func = 1 ,
. route_location = ROCKCHIP_ROUTE_GRF ,
. route_offset = 0xa0 ,
. route_val = BIT ( 16 + 11 ) ,
} , {
/* non-iomuxed emmc/flash pins on emmc-clk */
. bank_num = 0 ,
. pin = 24 ,
. func = 2 ,
. route_location = ROCKCHIP_ROUTE_GRF ,
. route_offset = 0xa0 ,
. route_val = BIT ( 16 + 11 ) | BIT ( 11 ) ,
} ,
} ;
2017-05-26 10:20:21 +03:00
static struct rockchip_mux_route_data rk3228_mux_route_data [ ] = {
{
/* pwm0-0 */
. bank_num = 0 ,
. pin = 26 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 ) ,
} , {
/* pwm0-1 */
. bank_num = 3 ,
. pin = 21 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 ) | BIT ( 0 ) ,
} , {
/* pwm1-0 */
. bank_num = 0 ,
. pin = 27 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 1 ) ,
} , {
/* pwm1-1 */
. bank_num = 0 ,
. pin = 30 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 1 ) | BIT ( 1 ) ,
} , {
/* pwm2-0 */
. bank_num = 0 ,
. pin = 28 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 2 ) ,
} , {
/* pwm2-1 */
. bank_num = 1 ,
. pin = 12 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 2 ) | BIT ( 2 ) ,
} , {
/* pwm3-0 */
. bank_num = 3 ,
. pin = 26 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 3 ) ,
} , {
/* pwm3-1 */
. bank_num = 1 ,
. pin = 11 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 3 ) | BIT ( 3 ) ,
} , {
/* sdio-0_d0 */
. bank_num = 1 ,
. pin = 1 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 4 ) ,
} , {
/* sdio-1_d0 */
. bank_num = 3 ,
. pin = 2 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 4 ) | BIT ( 4 ) ,
} , {
/* spi-0_rx */
. bank_num = 0 ,
. pin = 13 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 5 ) ,
} , {
/* spi-1_rx */
. bank_num = 2 ,
. pin = 0 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 5 ) | BIT ( 5 ) ,
} , {
/* emmc-0_cmd */
. bank_num = 1 ,
. pin = 22 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 7 ) ,
} , {
/* emmc-1_cmd */
. bank_num = 2 ,
. pin = 4 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 7 ) | BIT ( 7 ) ,
} , {
/* uart2-0_rx */
. bank_num = 1 ,
. pin = 19 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 8 ) ,
} , {
/* uart2-1_rx */
. bank_num = 1 ,
. pin = 10 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 8 ) | BIT ( 8 ) ,
} , {
/* uart1-0_rx */
. bank_num = 1 ,
. pin = 10 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 11 ) ,
} , {
/* uart1-1_rx */
. bank_num = 3 ,
. pin = 13 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 11 ) | BIT ( 11 ) ,
} ,
} ;
2017-10-21 11:53:10 +03:00
static struct rockchip_mux_route_data rk3288_mux_route_data [ ] = {
{
/* edphdmi_cecinoutt1 */
. bank_num = 7 ,
. pin = 16 ,
. func = 2 ,
. route_offset = 0x264 ,
. route_val = BIT ( 16 + 12 ) | BIT ( 12 ) ,
} , {
/* edphdmi_cecinout */
. bank_num = 7 ,
. pin = 23 ,
. func = 4 ,
. route_offset = 0x264 ,
. route_val = BIT ( 16 + 12 ) ,
} ,
} ;
2019-10-15 12:17:08 +03:00
static struct rockchip_mux_route_data rk3308_mux_route_data [ ] = {
{
/* rtc_clk */
. bank_num = 0 ,
. pin = 19 ,
. func = 1 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 0 ) | BIT ( 0 ) ,
} , {
/* uart2_rxm0 */
. bank_num = 1 ,
. pin = 22 ,
. func = 2 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 2 ) | BIT ( 16 + 3 ) ,
} , {
/* uart2_rxm1 */
. bank_num = 4 ,
. pin = 26 ,
. func = 2 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 2 ) | BIT ( 16 + 3 ) | BIT ( 2 ) ,
} , {
/* i2c3_sdam0 */
. bank_num = 0 ,
. pin = 15 ,
. func = 2 ,
. route_offset = 0x608 ,
. route_val = BIT ( 16 + 8 ) | BIT ( 16 + 9 ) ,
} , {
/* i2c3_sdam1 */
. bank_num = 3 ,
. pin = 12 ,
. func = 2 ,
. route_offset = 0x608 ,
. route_val = BIT ( 16 + 8 ) | BIT ( 16 + 9 ) | BIT ( 8 ) ,
} , {
/* i2c3_sdam2 */
. bank_num = 2 ,
. pin = 0 ,
. func = 3 ,
. route_offset = 0x608 ,
. route_val = BIT ( 16 + 8 ) | BIT ( 16 + 9 ) | BIT ( 9 ) ,
} , {
/* i2s-8ch-1-sclktxm0 */
. bank_num = 1 ,
. pin = 3 ,
. func = 2 ,
. route_offset = 0x308 ,
. route_val = BIT ( 16 + 3 ) ,
} , {
/* i2s-8ch-1-sclkrxm0 */
. bank_num = 1 ,
. pin = 4 ,
. func = 2 ,
. route_offset = 0x308 ,
. route_val = BIT ( 16 + 3 ) ,
} , {
/* i2s-8ch-1-sclktxm1 */
. bank_num = 1 ,
. pin = 13 ,
. func = 2 ,
. route_offset = 0x308 ,
. route_val = BIT ( 16 + 3 ) | BIT ( 3 ) ,
} , {
/* i2s-8ch-1-sclkrxm1 */
. bank_num = 1 ,
. pin = 14 ,
. func = 2 ,
. route_offset = 0x308 ,
. route_val = BIT ( 16 + 3 ) | BIT ( 3 ) ,
} , {
/* pdm-clkm0 */
. bank_num = 1 ,
. pin = 4 ,
. func = 3 ,
. route_offset = 0x308 ,
. route_val = BIT ( 16 + 12 ) | BIT ( 16 + 13 ) ,
} , {
/* pdm-clkm1 */
. bank_num = 1 ,
. pin = 14 ,
. func = 4 ,
. route_offset = 0x308 ,
. route_val = BIT ( 16 + 12 ) | BIT ( 16 + 13 ) | BIT ( 12 ) ,
} , {
/* pdm-clkm2 */
. bank_num = 2 ,
. pin = 6 ,
. func = 2 ,
. route_offset = 0x308 ,
. route_val = BIT ( 16 + 12 ) | BIT ( 16 + 13 ) | BIT ( 13 ) ,
} , {
/* pdm-clkm-m2 */
. bank_num = 2 ,
. pin = 4 ,
. func = 3 ,
. route_offset = 0x600 ,
. route_val = BIT ( 16 + 2 ) | BIT ( 2 ) ,
} , {
/* spi1_miso */
. bank_num = 3 ,
. pin = 10 ,
. func = 3 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 9 ) ,
} , {
/* spi1_miso_m1 */
. bank_num = 2 ,
. pin = 4 ,
. func = 2 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 9 ) | BIT ( 9 ) ,
} , {
/* owire_m0 */
. bank_num = 0 ,
. pin = 11 ,
. func = 3 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 10 ) | BIT ( 16 + 11 ) ,
} , {
/* owire_m1 */
. bank_num = 1 ,
. pin = 22 ,
. func = 7 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 10 ) | BIT ( 16 + 11 ) | BIT ( 10 ) ,
} , {
/* owire_m2 */
. bank_num = 2 ,
. pin = 2 ,
. func = 5 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 10 ) | BIT ( 16 + 11 ) | BIT ( 11 ) ,
} , {
/* can_rxd_m0 */
. bank_num = 0 ,
. pin = 11 ,
. func = 2 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 12 ) | BIT ( 16 + 13 ) ,
} , {
/* can_rxd_m1 */
. bank_num = 1 ,
. pin = 22 ,
. func = 5 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 12 ) | BIT ( 16 + 13 ) | BIT ( 12 ) ,
} , {
/* can_rxd_m2 */
. bank_num = 2 ,
. pin = 2 ,
. func = 4 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 12 ) | BIT ( 16 + 13 ) | BIT ( 13 ) ,
} , {
/* mac_rxd0_m0 */
. bank_num = 1 ,
. pin = 20 ,
. func = 3 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 14 ) ,
} , {
/* mac_rxd0_m1 */
. bank_num = 4 ,
. pin = 2 ,
. func = 2 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 14 ) | BIT ( 14 ) ,
} , {
/* uart3_rx */
. bank_num = 3 ,
. pin = 12 ,
. func = 4 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 15 ) ,
} , {
/* uart3_rx_m1 */
. bank_num = 0 ,
. pin = 17 ,
. func = 3 ,
. route_offset = 0x314 ,
. route_val = BIT ( 16 + 15 ) | BIT ( 15 ) ,
} ,
} ;
2017-05-26 10:20:22 +03:00
static struct rockchip_mux_route_data rk3328_mux_route_data [ ] = {
{
/* uart2dbg_rxm0 */
. bank_num = 1 ,
. pin = 1 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 ) | BIT ( 16 + 1 ) ,
} , {
/* uart2dbg_rxm1 */
. bank_num = 2 ,
. pin = 1 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 ) | BIT ( 16 + 1 ) | BIT ( 0 ) ,
} , {
2017-09-30 15:13:21 +03:00
/* gmac-m1_rxd0 */
2017-05-26 10:20:22 +03:00
. bank_num = 1 ,
. pin = 11 ,
. func = 2 ,
. route_offset = 0x50 ,
2017-09-30 15:13:21 +03:00
. route_val = BIT ( 16 + 2 ) | BIT ( 2 ) ,
} , {
/* gmac-m1-optimized_rxd3 */
. bank_num = 1 ,
. pin = 14 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 10 ) | BIT ( 10 ) ,
2017-05-26 10:20:22 +03:00
} , {
/* pdm_sdi0m0 */
. bank_num = 2 ,
. pin = 19 ,
. func = 2 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 3 ) ,
} , {
/* pdm_sdi0m1 */
. bank_num = 1 ,
. pin = 23 ,
. func = 3 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 3 ) | BIT ( 3 ) ,
} , {
/* spi_rxdm2 */
. bank_num = 3 ,
. pin = 2 ,
. func = 4 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 4 ) | BIT ( 16 + 5 ) | BIT ( 5 ) ,
} , {
/* i2s2_sdim0 */
. bank_num = 1 ,
. pin = 24 ,
. func = 1 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 6 ) ,
} , {
/* i2s2_sdim1 */
. bank_num = 3 ,
. pin = 2 ,
. func = 6 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 6 ) | BIT ( 6 ) ,
} , {
/* card_iom1 */
. bank_num = 2 ,
. pin = 22 ,
. func = 3 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 7 ) | BIT ( 7 ) ,
} , {
/* tsp_d5m1 */
. bank_num = 2 ,
. pin = 16 ,
. func = 3 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 8 ) | BIT ( 8 ) ,
} , {
/* cif_data5m1 */
. bank_num = 2 ,
. pin = 16 ,
. func = 4 ,
. route_offset = 0x50 ,
. route_val = BIT ( 16 + 9 ) | BIT ( 9 ) ,
} ,
} ;
2017-05-26 10:20:23 +03:00
static struct rockchip_mux_route_data rk3399_mux_route_data [ ] = {
{
/* uart2dbga_rx */
. bank_num = 4 ,
. pin = 8 ,
. func = 2 ,
. route_offset = 0xe21c ,
. route_val = BIT ( 16 + 10 ) | BIT ( 16 + 11 ) ,
} , {
/* uart2dbgb_rx */
. bank_num = 4 ,
. pin = 16 ,
. func = 2 ,
. route_offset = 0xe21c ,
. route_val = BIT ( 16 + 10 ) | BIT ( 16 + 11 ) | BIT ( 10 ) ,
} , {
/* uart2dbgc_rx */
. bank_num = 4 ,
. pin = 19 ,
. func = 1 ,
. route_offset = 0xe21c ,
. route_val = BIT ( 16 + 10 ) | BIT ( 16 + 11 ) | BIT ( 11 ) ,
} , {
/* pcie_clkreqn */
. bank_num = 2 ,
. pin = 26 ,
. func = 2 ,
. route_offset = 0xe21c ,
. route_val = BIT ( 16 + 14 ) ,
} , {
/* pcie_clkreqnb */
. bank_num = 4 ,
. pin = 24 ,
. func = 1 ,
. route_offset = 0xe21c ,
. route_val = BIT ( 16 + 14 ) | BIT ( 14 ) ,
} ,
} ;
2017-05-26 10:20:20 +03:00
static bool rockchip_get_mux_route ( struct rockchip_pin_bank * bank , int pin ,
2018-11-12 00:00:46 +03:00
int mux , u32 * loc , u32 * reg , u32 * value )
2017-05-26 10:20:20 +03:00
{
struct rockchip_pinctrl * info = bank - > drvdata ;
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
struct rockchip_mux_route_data * data ;
int i ;
for ( i = 0 ; i < ctrl - > niomux_routes ; i + + ) {
data = & ctrl - > iomux_routes [ i ] ;
if ( ( data - > bank_num = = bank - > bank_num ) & &
( data - > pin = = pin ) & & ( data - > func = = mux ) )
break ;
}
if ( i > = ctrl - > niomux_routes )
return false ;
2018-11-12 00:00:46 +03:00
* loc = data - > route_location ;
2017-05-26 10:20:20 +03:00
* reg = data - > route_offset ;
* value = data - > route_val ;
return true ;
}
2014-04-23 16:28:59 +04:00
static int rockchip_get_mux ( struct rockchip_pin_bank * bank , int pin )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
2014-06-16 03:36:05 +04:00
int iomux_num = ( pin / 8 ) ;
2014-06-16 03:37:23 +04:00
struct regmap * regmap ;
2014-05-05 15:58:20 +04:00
unsigned int val ;
2017-02-10 13:23:48 +03:00
int reg , ret , mask , mux_type ;
2014-04-23 16:28:59 +04:00
u8 bit ;
2014-06-16 03:36:05 +04:00
if ( iomux_num > 3 )
return - EINVAL ;
2014-06-16 03:37:49 +04:00
if ( bank - > iomux [ iomux_num ] . type & IOMUX_UNROUTED ) {
dev_err ( info - > dev , " pin %d is unrouted \n " , pin ) ;
return - EINVAL ;
}
2014-06-16 03:36:05 +04:00
if ( bank - > iomux [ iomux_num ] . type & IOMUX_GPIO_ONLY )
2014-04-23 16:28:59 +04:00
return RK_FUNC_GPIO ;
2014-06-16 03:37:23 +04:00
regmap = ( bank - > iomux [ iomux_num ] . type & IOMUX_SOURCE_PMU )
? info - > regmap_pmu : info - > regmap_base ;
2014-04-23 16:28:59 +04:00
/* get basic quadrupel of mux registers and the correct reg inside */
2017-02-10 13:23:48 +03:00
mux_type = bank - > iomux [ iomux_num ] . type ;
2014-06-16 03:36:33 +04:00
reg = bank - > iomux [ iomux_num ] . offset ;
2017-02-10 13:23:48 +03:00
if ( mux_type & IOMUX_WIDTH_4BIT ) {
2014-06-16 03:36:57 +04:00
if ( ( pin % 8 ) > = 4 )
reg + = 0x4 ;
bit = ( pin % 4 ) * 4 ;
2017-02-10 13:23:47 +03:00
mask = 0xf ;
2017-02-10 13:23:48 +03:00
} else if ( mux_type & IOMUX_WIDTH_3BIT ) {
2017-02-10 13:23:47 +03:00
if ( ( pin % 8 ) > = 5 )
reg + = 0x4 ;
bit = ( pin % 8 % 5 ) * 3 ;
mask = 0x7 ;
2014-06-16 03:36:57 +04:00
} else {
bit = ( pin % 8 ) * 2 ;
2017-02-10 13:23:47 +03:00
mask = 0x3 ;
2014-06-16 03:36:57 +04:00
}
2014-04-23 16:28:59 +04:00
2017-07-21 09:27:14 +03:00
if ( bank - > recalced_mask & BIT ( pin ) )
rockchip_get_recalced_mux ( bank , pin , & reg , & bit , & mask ) ;
2017-02-10 13:23:48 +03:00
2014-06-16 03:37:23 +04:00
ret = regmap_read ( regmap , reg , & val ) ;
2014-05-05 15:58:20 +04:00
if ( ret )
return ret ;
2014-06-16 03:36:57 +04:00
return ( ( val > > bit ) & mask ) ;
2014-04-23 16:28:59 +04:00
}
2017-03-23 13:59:30 +03:00
static int rockchip_verify_mux ( struct rockchip_pin_bank * bank ,
int pin , int mux )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
int iomux_num = ( pin / 8 ) ;
if ( iomux_num > 3 )
return - EINVAL ;
if ( bank - > iomux [ iomux_num ] . type & IOMUX_UNROUTED ) {
dev_err ( info - > dev , " pin %d is unrouted \n " , pin ) ;
return - EINVAL ;
}
if ( bank - > iomux [ iomux_num ] . type & IOMUX_GPIO_ONLY ) {
if ( mux ! = RK_FUNC_GPIO ) {
dev_err ( info - > dev ,
" pin %d only supports a gpio mux \n " , pin ) ;
return - ENOTSUPP ;
}
}
return 0 ;
}
2013-06-11 00:16:22 +04:00
/*
* Set a new mux function for a pin .
*
* The register is divided into the upper and lower 16 bit . When changing
* a value , the previous register value is not read and changed . Instead
* it seems the changed bits are marked in the upper 16 bit , while the
* changed value gets set in the same offset in the lower 16 bit .
* All pin settings seem to be 2 bit wide in both the upper and lower
* parts .
* @ bank : pin bank to change
* @ pin : pin to change
* @ mux : new mux function to set
*/
2014-03-26 03:57:00 +04:00
static int rockchip_set_mux ( struct rockchip_pin_bank * bank , int pin , int mux )
2013-06-11 00:16:22 +04:00
{
struct rockchip_pinctrl * info = bank - > drvdata ;
2014-06-16 03:36:05 +04:00
int iomux_num = ( pin / 8 ) ;
2014-06-16 03:37:23 +04:00
struct regmap * regmap ;
2017-02-10 13:23:48 +03:00
int reg , ret , mask , mux_type ;
2013-06-11 00:16:22 +04:00
u8 bit ;
2018-11-12 00:00:46 +03:00
u32 data , rmask , route_location , route_reg , route_val ;
2013-06-11 00:16:22 +04:00
2017-03-23 13:59:30 +03:00
ret = rockchip_verify_mux ( bank , pin , mux ) ;
if ( ret < 0 )
return ret ;
2014-06-16 03:37:49 +04:00
2017-03-23 13:59:30 +03:00
if ( bank - > iomux [ iomux_num ] . type & IOMUX_GPIO_ONLY )
return 0 ;
2014-03-26 03:57:52 +04:00
2013-06-11 00:16:22 +04:00
dev_dbg ( info - > dev , " setting mux of GPIO%d-%d to %d \n " ,
bank - > bank_num , pin , mux ) ;
2014-06-16 03:37:23 +04:00
regmap = ( bank - > iomux [ iomux_num ] . type & IOMUX_SOURCE_PMU )
? info - > regmap_pmu : info - > regmap_base ;
2013-06-11 00:16:22 +04:00
/* get basic quadrupel of mux registers and the correct reg inside */
2017-02-10 13:23:48 +03:00
mux_type = bank - > iomux [ iomux_num ] . type ;
2014-06-16 03:36:33 +04:00
reg = bank - > iomux [ iomux_num ] . offset ;
2017-02-10 13:23:48 +03:00
if ( mux_type & IOMUX_WIDTH_4BIT ) {
2014-06-16 03:36:57 +04:00
if ( ( pin % 8 ) > = 4 )
reg + = 0x4 ;
bit = ( pin % 4 ) * 4 ;
2017-02-10 13:23:47 +03:00
mask = 0xf ;
2017-02-10 13:23:48 +03:00
} else if ( mux_type & IOMUX_WIDTH_3BIT ) {
2017-02-10 13:23:47 +03:00
if ( ( pin % 8 ) > = 5 )
reg + = 0x4 ;
bit = ( pin % 8 % 5 ) * 3 ;
mask = 0x7 ;
2014-06-16 03:36:57 +04:00
} else {
bit = ( pin % 8 ) * 2 ;
2017-02-10 13:23:47 +03:00
mask = 0x3 ;
2014-06-16 03:36:57 +04:00
}
2013-06-11 00:16:22 +04:00
2017-07-21 09:27:14 +03:00
if ( bank - > recalced_mask & BIT ( pin ) )
rockchip_get_recalced_mux ( bank , pin , & reg , & bit , & mask ) ;
2017-02-10 13:23:48 +03:00
2017-05-26 10:20:20 +03:00
if ( bank - > route_mask & BIT ( pin ) ) {
2018-11-12 00:00:46 +03:00
if ( rockchip_get_mux_route ( bank , pin , mux , & route_location ,
& route_reg , & route_val ) ) {
struct regmap * route_regmap = regmap ;
/* handle special locations */
switch ( route_location ) {
case ROCKCHIP_ROUTE_PMU :
route_regmap = info - > regmap_pmu ;
break ;
case ROCKCHIP_ROUTE_GRF :
route_regmap = info - > regmap_base ;
break ;
}
ret = regmap_write ( route_regmap , route_reg , route_val ) ;
2017-05-26 10:20:20 +03:00
if ( ret )
return ret ;
}
}
2014-06-16 03:36:57 +04:00
data = ( mask < < ( bit + 16 ) ) ;
2014-08-01 09:58:00 +04:00
rmask = data | ( data > > 16 ) ;
2014-06-16 03:36:57 +04:00
data | = ( mux & mask ) < < bit ;
2014-08-01 09:58:00 +04:00
ret = regmap_update_bits ( regmap , reg , rmask , data ) ;
2013-06-11 00:16:22 +04:00
2014-05-05 15:58:20 +04:00
return ret ;
2013-06-11 00:16:22 +04:00
}
2018-05-14 14:59:51 +03:00
# define PX30_PULL_PMU_OFFSET 0x10
# define PX30_PULL_GRF_OFFSET 0x60
# define PX30_PULL_BITS_PER_PIN 2
# define PX30_PULL_PINS_PER_REG 8
# define PX30_PULL_BANK_STRIDE 16
static void px30_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The first 32 pins of the first bank are located in PMU */
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
* reg = PX30_PULL_PMU_OFFSET ;
} else {
* regmap = info - > regmap_base ;
* reg = PX30_PULL_GRF_OFFSET ;
/* correct the offset, as we're starting with the 2nd bank */
* reg - = 0x10 ;
* reg + = bank - > bank_num * PX30_PULL_BANK_STRIDE ;
}
* reg + = ( ( pin_num / PX30_PULL_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % PX30_PULL_PINS_PER_REG ) ;
* bit * = PX30_PULL_BITS_PER_PIN ;
}
# define PX30_DRV_PMU_OFFSET 0x20
# define PX30_DRV_GRF_OFFSET 0xf0
# define PX30_DRV_BITS_PER_PIN 2
# define PX30_DRV_PINS_PER_REG 8
# define PX30_DRV_BANK_STRIDE 16
static void px30_calc_drv_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The first 32 pins of the first bank are located in PMU */
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
* reg = PX30_DRV_PMU_OFFSET ;
} else {
* regmap = info - > regmap_base ;
* reg = PX30_DRV_GRF_OFFSET ;
/* correct the offset, as we're starting with the 2nd bank */
* reg - = 0x10 ;
* reg + = bank - > bank_num * PX30_DRV_BANK_STRIDE ;
}
* reg + = ( ( pin_num / PX30_DRV_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % PX30_DRV_PINS_PER_REG ) ;
* bit * = PX30_DRV_BITS_PER_PIN ;
}
# define PX30_SCHMITT_PMU_OFFSET 0x38
# define PX30_SCHMITT_GRF_OFFSET 0xc0
# define PX30_SCHMITT_PINS_PER_PMU_REG 16
# define PX30_SCHMITT_BANK_STRIDE 16
# define PX30_SCHMITT_PINS_PER_GRF_REG 8
static int px30_calc_schmitt_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num ,
struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
int pins_per_reg ;
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
* reg = PX30_SCHMITT_PMU_OFFSET ;
pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG ;
} else {
* regmap = info - > regmap_base ;
* reg = PX30_SCHMITT_GRF_OFFSET ;
pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG ;
* reg + = ( bank - > bank_num - 1 ) * PX30_SCHMITT_BANK_STRIDE ;
}
* reg + = ( ( pin_num / pins_per_reg ) * 4 ) ;
* bit = pin_num % pins_per_reg ;
return 0 ;
}
2017-03-17 20:18:36 +03:00
# define RV1108_PULL_PMU_OFFSET 0x10
# define RV1108_PULL_OFFSET 0x110
# define RV1108_PULL_PINS_PER_REG 8
# define RV1108_PULL_BITS_PER_PIN 2
# define RV1108_PULL_BANK_STRIDE 16
2016-11-15 13:02:43 +03:00
2017-03-17 20:18:36 +03:00
static void rv1108_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
2016-11-15 13:02:43 +03:00
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The first 24 pins of the first bank are located in PMU */
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
2017-03-17 20:18:36 +03:00
* reg = RV1108_PULL_PMU_OFFSET ;
2016-11-15 13:02:43 +03:00
} else {
2017-03-17 20:18:36 +03:00
* reg = RV1108_PULL_OFFSET ;
2016-11-15 13:02:43 +03:00
* regmap = info - > regmap_base ;
/* correct the offset, as we're starting with the 2nd bank */
* reg - = 0x10 ;
2017-03-17 20:18:36 +03:00
* reg + = bank - > bank_num * RV1108_PULL_BANK_STRIDE ;
2016-11-15 13:02:43 +03:00
}
2017-03-17 20:18:36 +03:00
* reg + = ( ( pin_num / RV1108_PULL_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RV1108_PULL_PINS_PER_REG ) ;
* bit * = RV1108_PULL_BITS_PER_PIN ;
2016-11-15 13:02:43 +03:00
}
2017-03-17 20:18:36 +03:00
# define RV1108_DRV_PMU_OFFSET 0x20
# define RV1108_DRV_GRF_OFFSET 0x210
# define RV1108_DRV_BITS_PER_PIN 2
# define RV1108_DRV_PINS_PER_REG 8
# define RV1108_DRV_BANK_STRIDE 16
2016-11-15 13:02:43 +03:00
2017-03-17 20:18:36 +03:00
static void rv1108_calc_drv_reg_and_bit ( struct rockchip_pin_bank * bank ,
2016-11-15 13:02:43 +03:00
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The first 24 pins of the first bank are located in PMU */
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
2017-03-17 20:18:36 +03:00
* reg = RV1108_DRV_PMU_OFFSET ;
2016-11-15 13:02:43 +03:00
} else {
* regmap = info - > regmap_base ;
2017-03-17 20:18:36 +03:00
* reg = RV1108_DRV_GRF_OFFSET ;
2016-11-15 13:02:43 +03:00
/* correct the offset, as we're starting with the 2nd bank */
* reg - = 0x10 ;
2017-03-17 20:18:36 +03:00
* reg + = bank - > bank_num * RV1108_DRV_BANK_STRIDE ;
2016-11-15 13:02:43 +03:00
}
2017-03-17 20:18:36 +03:00
* reg + = ( ( pin_num / RV1108_DRV_PINS_PER_REG ) * 4 ) ;
* bit = pin_num % RV1108_DRV_PINS_PER_REG ;
* bit * = RV1108_DRV_BITS_PER_PIN ;
2016-11-15 13:02:43 +03:00
}
2017-07-31 13:10:22 +03:00
# define RV1108_SCHMITT_PMU_OFFSET 0x30
# define RV1108_SCHMITT_GRF_OFFSET 0x388
# define RV1108_SCHMITT_BANK_STRIDE 8
# define RV1108_SCHMITT_PINS_PER_GRF_REG 16
# define RV1108_SCHMITT_PINS_PER_PMU_REG 8
static int rv1108_calc_schmitt_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num ,
struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
int pins_per_reg ;
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
* reg = RV1108_SCHMITT_PMU_OFFSET ;
pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG ;
} else {
* regmap = info - > regmap_base ;
* reg = RV1108_SCHMITT_GRF_OFFSET ;
pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG ;
* reg + = ( bank - > bank_num - 1 ) * RV1108_SCHMITT_BANK_STRIDE ;
}
* reg + = ( ( pin_num / pins_per_reg ) * 4 ) ;
* bit = pin_num % pins_per_reg ;
return 0 ;
}
2019-10-15 12:17:08 +03:00
# define RK3308_SCHMITT_PINS_PER_REG 8
# define RK3308_SCHMITT_BANK_STRIDE 16
# define RK3308_SCHMITT_GRF_OFFSET 0x1a0
static int rk3308_calc_schmitt_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
* regmap = info - > regmap_base ;
* reg = RK3308_SCHMITT_GRF_OFFSET ;
* reg + = bank - > bank_num * RK3308_SCHMITT_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3308_SCHMITT_PINS_PER_REG ) * 4 ) ;
* bit = pin_num % RK3308_SCHMITT_PINS_PER_REG ;
return 0 ;
}
2013-10-16 03:07:20 +04:00
# define RK2928_PULL_OFFSET 0x118
# define RK2928_PULL_PINS_PER_REG 16
# define RK2928_PULL_BANK_STRIDE 8
static void rk2928_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
2014-05-05 15:58:20 +04:00
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
2013-10-16 03:07:20 +04:00
{
struct rockchip_pinctrl * info = bank - > drvdata ;
2014-05-05 15:58:20 +04:00
* regmap = info - > regmap_base ;
* reg = RK2928_PULL_OFFSET ;
2013-10-16 03:07:20 +04:00
* reg + = bank - > bank_num * RK2928_PULL_BANK_STRIDE ;
* reg + = ( pin_num / RK2928_PULL_PINS_PER_REG ) * 4 ;
* bit = pin_num % RK2928_PULL_PINS_PER_REG ;
} ;
2017-07-21 09:27:15 +03:00
# define RK3128_PULL_OFFSET 0x118
static void rk3128_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
* regmap = info - > regmap_base ;
* reg = RK3128_PULL_OFFSET ;
* reg + = bank - > bank_num * RK2928_PULL_BANK_STRIDE ;
* reg + = ( ( pin_num / RK2928_PULL_PINS_PER_REG ) * 4 ) ;
* bit = pin_num % RK2928_PULL_PINS_PER_REG ;
}
2014-05-05 15:58:00 +04:00
# define RK3188_PULL_OFFSET 0x164
2013-10-16 03:08:42 +04:00
# define RK3188_PULL_BITS_PER_PIN 2
# define RK3188_PULL_PINS_PER_REG 8
# define RK3188_PULL_BANK_STRIDE 16
2014-05-05 15:59:09 +04:00
# define RK3188_PULL_PMU_OFFSET 0x64
2013-10-16 03:08:42 +04:00
static void rk3188_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
2014-05-05 15:58:20 +04:00
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
2013-10-16 03:08:42 +04:00
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The first 12 pins of the first bank are located elsewhere */
2014-06-16 03:36:05 +04:00
if ( bank - > bank_num = = 0 & & pin_num < 12 ) {
2014-05-05 15:59:09 +04:00
* regmap = info - > regmap_pmu ? info - > regmap_pmu
: bank - > regmap_pull ;
* reg = info - > regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0 ;
2014-05-05 15:58:20 +04:00
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
2013-10-16 03:08:42 +04:00
* bit = pin_num % RK3188_PULL_PINS_PER_REG ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
} else {
2014-05-05 15:58:20 +04:00
* regmap = info - > regmap_pull ? info - > regmap_pull
: info - > regmap_base ;
* reg = info - > regmap_pull ? 0 : RK3188_PULL_OFFSET ;
2014-05-05 15:58:00 +04:00
/* correct the offset, as it is the 2nd pull register */
* reg - = 4 ;
2013-10-16 03:08:42 +04:00
* reg + = bank - > bank_num * RK3188_PULL_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
/*
* The bits in these registers have an inverse ordering
* with the lowest pin being in bits 15 : 14 and the highest
* pin in bits 1 : 0
*/
* bit = 7 - ( pin_num % RK3188_PULL_PINS_PER_REG ) ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
}
}
2014-06-16 03:38:14 +04:00
# define RK3288_PULL_OFFSET 0x140
static void rk3288_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The first 24 pins of the first bank are located in PMU */
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
* reg = RK3188_PULL_PMU_OFFSET ;
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
* bit = pin_num % RK3188_PULL_PINS_PER_REG ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
} else {
* regmap = info - > regmap_base ;
* reg = RK3288_PULL_OFFSET ;
/* correct the offset, as we're starting with the 2nd bank */
* reg - = 0x10 ;
* reg + = bank - > bank_num * RK3188_PULL_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RK3188_PULL_PINS_PER_REG ) ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
}
}
2014-07-20 03:50:11 +04:00
# define RK3288_DRV_PMU_OFFSET 0x70
# define RK3288_DRV_GRF_OFFSET 0x1c0
# define RK3288_DRV_BITS_PER_PIN 2
# define RK3288_DRV_PINS_PER_REG 8
# define RK3288_DRV_BANK_STRIDE 16
static void rk3288_calc_drv_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The first 24 pins of the first bank are located in PMU */
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
* reg = RK3288_DRV_PMU_OFFSET ;
* reg + = ( ( pin_num / RK3288_DRV_PINS_PER_REG ) * 4 ) ;
* bit = pin_num % RK3288_DRV_PINS_PER_REG ;
* bit * = RK3288_DRV_BITS_PER_PIN ;
} else {
* regmap = info - > regmap_base ;
* reg = RK3288_DRV_GRF_OFFSET ;
/* correct the offset, as we're starting with the 2nd bank */
* reg - = 0x10 ;
* reg + = bank - > bank_num * RK3288_DRV_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3288_DRV_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RK3288_DRV_PINS_PER_REG ) ;
* bit * = RK3288_DRV_BITS_PER_PIN ;
}
}
2015-12-09 12:04:06 +03:00
# define RK3228_PULL_OFFSET 0x100
static void rk3228_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
* regmap = info - > regmap_base ;
* reg = RK3228_PULL_OFFSET ;
* reg + = bank - > bank_num * RK3188_PULL_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RK3188_PULL_PINS_PER_REG ) ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
}
# define RK3228_DRV_GRF_OFFSET 0x200
static void rk3228_calc_drv_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
* regmap = info - > regmap_base ;
* reg = RK3228_DRV_GRF_OFFSET ;
* reg + = bank - > bank_num * RK3288_DRV_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3288_DRV_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RK3288_DRV_PINS_PER_REG ) ;
* bit * = RK3288_DRV_BITS_PER_PIN ;
}
2019-10-15 12:17:08 +03:00
# define RK3308_PULL_OFFSET 0xa0
static void rk3308_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
* regmap = info - > regmap_base ;
* reg = RK3308_PULL_OFFSET ;
* reg + = bank - > bank_num * RK3188_PULL_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RK3188_PULL_PINS_PER_REG ) ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
}
# define RK3308_DRV_GRF_OFFSET 0x100
static void rk3308_calc_drv_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
* regmap = info - > regmap_base ;
* reg = RK3308_DRV_GRF_OFFSET ;
* reg + = bank - > bank_num * RK3288_DRV_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3288_DRV_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RK3288_DRV_PINS_PER_REG ) ;
* bit * = RK3288_DRV_BITS_PER_PIN ;
}
2015-06-13 00:51:01 +03:00
# define RK3368_PULL_GRF_OFFSET 0x100
# define RK3368_PULL_PMU_OFFSET 0x10
static void rk3368_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The first 32 pins of the first bank are located in PMU */
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
* reg = RK3368_PULL_PMU_OFFSET ;
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
* bit = pin_num % RK3188_PULL_PINS_PER_REG ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
} else {
* regmap = info - > regmap_base ;
* reg = RK3368_PULL_GRF_OFFSET ;
/* correct the offset, as we're starting with the 2nd bank */
* reg - = 0x10 ;
* reg + = bank - > bank_num * RK3188_PULL_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RK3188_PULL_PINS_PER_REG ) ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
}
}
# define RK3368_DRV_PMU_OFFSET 0x20
# define RK3368_DRV_GRF_OFFSET 0x200
static void rk3368_calc_drv_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The first 32 pins of the first bank are located in PMU */
if ( bank - > bank_num = = 0 ) {
* regmap = info - > regmap_pmu ;
* reg = RK3368_DRV_PMU_OFFSET ;
* reg + = ( ( pin_num / RK3288_DRV_PINS_PER_REG ) * 4 ) ;
* bit = pin_num % RK3288_DRV_PINS_PER_REG ;
* bit * = RK3288_DRV_BITS_PER_PIN ;
} else {
* regmap = info - > regmap_base ;
* reg = RK3368_DRV_GRF_OFFSET ;
/* correct the offset, as we're starting with the 2nd bank */
* reg - = 0x10 ;
* reg + = bank - > bank_num * RK3288_DRV_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3288_DRV_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RK3288_DRV_PINS_PER_REG ) ;
* bit * = RK3288_DRV_BITS_PER_PIN ;
}
}
2016-02-01 05:58:21 +03:00
# define RK3399_PULL_GRF_OFFSET 0xe040
# define RK3399_PULL_PMU_OFFSET 0x40
# define RK3399_DRV_3BITS_PER_PIN 3
static void rk3399_calc_pull_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
/* The bank0:16 and bank1:32 pins are located in PMU */
if ( ( bank - > bank_num = = 0 ) | | ( bank - > bank_num = = 1 ) ) {
* regmap = info - > regmap_pmu ;
* reg = RK3399_PULL_PMU_OFFSET ;
* reg + = bank - > bank_num * RK3188_PULL_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
* bit = pin_num % RK3188_PULL_PINS_PER_REG ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
} else {
* regmap = info - > regmap_base ;
* reg = RK3399_PULL_GRF_OFFSET ;
/* correct the offset, as we're starting with the 3rd bank */
* reg - = 0x20 ;
* reg + = bank - > bank_num * RK3188_PULL_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3188_PULL_PINS_PER_REG ) * 4 ) ;
* bit = ( pin_num % RK3188_PULL_PINS_PER_REG ) ;
* bit * = RK3188_PULL_BITS_PER_PIN ;
}
}
static void rk3399_calc_drv_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num , struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
int drv_num = ( pin_num / 8 ) ;
/* The bank0:16 and bank1:32 pins are located in PMU */
if ( ( bank - > bank_num = = 0 ) | | ( bank - > bank_num = = 1 ) )
* regmap = info - > regmap_pmu ;
else
* regmap = info - > regmap_base ;
* reg = bank - > drv [ drv_num ] . offset ;
if ( ( bank - > drv [ drv_num ] . drv_type = = DRV_TYPE_IO_1V8_3V0_AUTO ) | |
( bank - > drv [ drv_num ] . drv_type = = DRV_TYPE_IO_3V3_ONLY ) )
* bit = ( pin_num % 8 ) * 3 ;
else
* bit = ( pin_num % 8 ) * 2 ;
}
static int rockchip_perpin_drv_list [ DRV_TYPE_MAX ] [ 8 ] = {
{ 2 , 4 , 8 , 12 , - 1 , - 1 , - 1 , - 1 } ,
{ 3 , 6 , 9 , 12 , - 1 , - 1 , - 1 , - 1 } ,
{ 5 , 10 , 15 , 20 , - 1 , - 1 , - 1 , - 1 } ,
{ 4 , 6 , 8 , 10 , 12 , 14 , 16 , 18 } ,
{ 4 , 7 , 10 , 13 , 16 , 19 , 22 , 26 }
} ;
2015-06-13 00:50:11 +03:00
static int rockchip_get_drive_perpin ( struct rockchip_pin_bank * bank ,
int pin_num )
2014-07-20 03:50:11 +04:00
{
2015-06-13 00:50:11 +03:00
struct rockchip_pinctrl * info = bank - > drvdata ;
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
2014-07-20 03:50:11 +04:00
struct regmap * regmap ;
int reg , ret ;
2016-02-01 05:58:21 +03:00
u32 data , temp , rmask_bits ;
2014-07-20 03:50:11 +04:00
u8 bit ;
2016-02-01 05:58:21 +03:00
int drv_type = bank - > drv [ pin_num / 8 ] . drv_type ;
2014-07-20 03:50:11 +04:00
2015-06-13 00:50:11 +03:00
ctrl - > drv_calc_reg ( bank , pin_num , & regmap , & reg , & bit ) ;
2014-07-20 03:50:11 +04:00
2016-02-01 05:58:21 +03:00
switch ( drv_type ) {
case DRV_TYPE_IO_1V8_3V0_AUTO :
case DRV_TYPE_IO_3V3_ONLY :
rmask_bits = RK3399_DRV_3BITS_PER_PIN ;
switch ( bit ) {
case 0 . . . 12 :
/* regular case, nothing to do */
break ;
case 15 :
/*
* drive - strength offset is special , as it is
* spread over 2 registers
*/
ret = regmap_read ( regmap , reg , & data ) ;
if ( ret )
return ret ;
ret = regmap_read ( regmap , reg + 0x4 , & temp ) ;
if ( ret )
return ret ;
/*
* the bit data [ 15 ] contains bit 0 of the value
* while temp [ 1 : 0 ] contains bits 2 and 1
*/
data > > = 15 ;
temp & = 0x3 ;
temp < < = 1 ;
data | = temp ;
return rockchip_perpin_drv_list [ drv_type ] [ data ] ;
case 18 . . . 21 :
/* setting fully enclosed in the second register */
reg + = 4 ;
bit - = 16 ;
break ;
default :
dev_err ( info - > dev , " unsupported bit: %d for pinctrl drive type: %d \n " ,
bit , drv_type ) ;
return - EINVAL ;
}
break ;
case DRV_TYPE_IO_DEFAULT :
case DRV_TYPE_IO_1V8_OR_3V0 :
case DRV_TYPE_IO_1V8_ONLY :
rmask_bits = RK3288_DRV_BITS_PER_PIN ;
break ;
default :
dev_err ( info - > dev , " unsupported pinctrl drive type: %d \n " ,
drv_type ) ;
return - EINVAL ;
}
2014-07-20 03:50:11 +04:00
ret = regmap_read ( regmap , reg , & data ) ;
if ( ret )
return ret ;
data > > = bit ;
2016-02-01 05:58:21 +03:00
data & = ( 1 < < rmask_bits ) - 1 ;
2014-07-20 03:50:11 +04:00
2016-02-01 05:58:21 +03:00
return rockchip_perpin_drv_list [ drv_type ] [ data ] ;
2014-07-20 03:50:11 +04:00
}
2015-06-13 00:50:11 +03:00
static int rockchip_set_drive_perpin ( struct rockchip_pin_bank * bank ,
int pin_num , int strength )
2014-07-20 03:50:11 +04:00
{
struct rockchip_pinctrl * info = bank - > drvdata ;
2015-06-13 00:50:11 +03:00
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
2014-07-20 03:50:11 +04:00
struct regmap * regmap ;
int reg , ret , i ;
2016-02-01 05:58:21 +03:00
u32 data , rmask , rmask_bits , temp ;
2014-07-20 03:50:11 +04:00
u8 bit ;
2016-02-01 05:58:21 +03:00
int drv_type = bank - > drv [ pin_num / 8 ] . drv_type ;
dev_dbg ( info - > dev , " setting drive of GPIO%d-%d to %d \n " ,
bank - > bank_num , pin_num , strength ) ;
2014-07-20 03:50:11 +04:00
2015-06-13 00:50:11 +03:00
ctrl - > drv_calc_reg ( bank , pin_num , & regmap , & reg , & bit ) ;
2014-07-20 03:50:11 +04:00
ret = - EINVAL ;
2016-02-01 05:58:21 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( rockchip_perpin_drv_list [ drv_type ] ) ; i + + ) {
if ( rockchip_perpin_drv_list [ drv_type ] [ i ] = = strength ) {
2014-07-20 03:50:11 +04:00
ret = i ;
break ;
2016-02-01 05:58:21 +03:00
} else if ( rockchip_perpin_drv_list [ drv_type ] [ i ] < 0 ) {
ret = rockchip_perpin_drv_list [ drv_type ] [ i ] ;
break ;
2014-07-20 03:50:11 +04:00
}
}
if ( ret < 0 ) {
dev_err ( info - > dev , " unsupported driver strength %d \n " ,
strength ) ;
return ret ;
}
2016-02-01 05:58:21 +03:00
switch ( drv_type ) {
case DRV_TYPE_IO_1V8_3V0_AUTO :
case DRV_TYPE_IO_3V3_ONLY :
rmask_bits = RK3399_DRV_3BITS_PER_PIN ;
switch ( bit ) {
case 0 . . . 12 :
/* regular case, nothing to do */
break ;
case 15 :
/*
* drive - strength offset is special , as it is spread
* over 2 registers , the bit data [ 15 ] contains bit 0
* of the value while temp [ 1 : 0 ] contains bits 2 and 1
*/
data = ( ret & 0x1 ) < < 15 ;
temp = ( ret > > 0x1 ) & 0x3 ;
rmask = BIT ( 15 ) | BIT ( 31 ) ;
data | = BIT ( 31 ) ;
ret = regmap_update_bits ( regmap , reg , rmask , data ) ;
2017-03-23 13:59:28 +03:00
if ( ret )
2016-02-01 05:58:21 +03:00
return ret ;
rmask = 0x3 | ( 0x3 < < 16 ) ;
temp | = ( 0x3 < < 16 ) ;
reg + = 0x4 ;
ret = regmap_update_bits ( regmap , reg , rmask , temp ) ;
return ret ;
case 18 . . . 21 :
/* setting fully enclosed in the second register */
reg + = 4 ;
bit - = 16 ;
break ;
default :
dev_err ( info - > dev , " unsupported bit: %d for pinctrl drive type: %d \n " ,
bit , drv_type ) ;
return - EINVAL ;
}
break ;
case DRV_TYPE_IO_DEFAULT :
case DRV_TYPE_IO_1V8_OR_3V0 :
case DRV_TYPE_IO_1V8_ONLY :
rmask_bits = RK3288_DRV_BITS_PER_PIN ;
break ;
default :
dev_err ( info - > dev , " unsupported pinctrl drive type: %d \n " ,
drv_type ) ;
return - EINVAL ;
}
2014-07-20 03:50:11 +04:00
/* enable the write to the equivalent lower bits */
2016-02-01 05:58:21 +03:00
data = ( ( 1 < < rmask_bits ) - 1 ) < < ( bit + 16 ) ;
2014-08-01 09:58:00 +04:00
rmask = data | ( data > > 16 ) ;
2014-07-20 03:50:11 +04:00
data | = ( ret < < bit ) ;
2014-08-01 09:58:00 +04:00
ret = regmap_update_bits ( regmap , reg , rmask , data ) ;
2014-07-20 03:50:11 +04:00
return ret ;
}
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
static int rockchip_pull_list [ PULL_TYPE_MAX ] [ 4 ] = {
{
PIN_CONFIG_BIAS_DISABLE ,
PIN_CONFIG_BIAS_PULL_UP ,
PIN_CONFIG_BIAS_PULL_DOWN ,
PIN_CONFIG_BIAS_BUS_HOLD
} ,
{
PIN_CONFIG_BIAS_DISABLE ,
PIN_CONFIG_BIAS_PULL_DOWN ,
PIN_CONFIG_BIAS_DISABLE ,
PIN_CONFIG_BIAS_PULL_UP
} ,
} ;
2013-06-11 00:16:22 +04:00
static int rockchip_get_pull ( struct rockchip_pin_bank * bank , int pin_num )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
2014-05-05 15:58:20 +04:00
struct regmap * regmap ;
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
int reg , ret , pull_type ;
2013-06-11 00:16:22 +04:00
u8 bit ;
2013-10-16 03:08:42 +04:00
u32 data ;
2013-06-11 00:16:22 +04:00
/* rk3066b does support any pulls */
2013-10-16 03:07:20 +04:00
if ( ctrl - > type = = RK3066B )
2013-06-11 00:16:22 +04:00
return PIN_CONFIG_BIAS_DISABLE ;
2014-05-05 15:58:20 +04:00
ctrl - > pull_calc_reg ( bank , pin_num , & regmap , & reg , & bit ) ;
ret = regmap_read ( regmap , reg , & data ) ;
if ( ret )
return ret ;
2013-10-16 03:08:42 +04:00
2013-10-16 03:07:20 +04:00
switch ( ctrl - > type ) {
case RK2928 :
2017-07-21 09:27:15 +03:00
case RK3128 :
2014-05-05 15:58:20 +04:00
return ! ( data & BIT ( bit ) )
2013-06-11 00:16:22 +04:00
? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
: PIN_CONFIG_BIAS_DISABLE ;
2018-05-14 14:59:51 +03:00
case PX30 :
2017-03-17 20:18:36 +03:00
case RV1108 :
2013-10-16 03:07:20 +04:00
case RK3188 :
2014-07-20 03:49:17 +04:00
case RK3288 :
2019-10-15 12:17:08 +03:00
case RK3308 :
2015-06-13 00:51:01 +03:00
case RK3368 :
2016-02-01 05:58:21 +03:00
case RK3399 :
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
pull_type = bank - > pull_type [ pin_num / 8 ] ;
2014-05-05 15:58:20 +04:00
data > > = bit ;
2013-10-16 03:08:42 +04:00
data & = ( 1 < < RK3188_PULL_BITS_PER_PIN ) - 1 ;
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
return rockchip_pull_list [ pull_type ] [ data ] ;
2013-10-16 03:07:20 +04:00
default :
dev_err ( info - > dev , " unsupported pinctrl type \n " ) ;
return - EINVAL ;
} ;
2013-06-11 00:16:22 +04:00
}
static int rockchip_set_pull ( struct rockchip_pin_bank * bank ,
int pin_num , int pull )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
2014-05-05 15:58:20 +04:00
struct regmap * regmap ;
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
int reg , ret , i , pull_type ;
2013-06-11 00:16:22 +04:00
u8 bit ;
2014-08-01 09:58:00 +04:00
u32 data , rmask ;
2013-06-11 00:16:22 +04:00
dev_dbg ( info - > dev , " setting pull of GPIO%d-%d to %d \n " ,
bank - > bank_num , pin_num , pull ) ;
/* rk3066b does support any pulls */
2013-10-16 03:07:20 +04:00
if ( ctrl - > type = = RK3066B )
2013-06-11 00:16:22 +04:00
return pull ? - EINVAL : 0 ;
2014-05-05 15:58:20 +04:00
ctrl - > pull_calc_reg ( bank , pin_num , & regmap , & reg , & bit ) ;
2013-10-16 03:08:42 +04:00
2013-10-16 03:07:20 +04:00
switch ( ctrl - > type ) {
case RK2928 :
2017-07-21 09:27:15 +03:00
case RK3128 :
2013-06-11 00:16:22 +04:00
data = BIT ( bit + 16 ) ;
if ( pull = = PIN_CONFIG_BIAS_DISABLE )
data | = BIT ( bit ) ;
2014-05-05 15:58:20 +04:00
ret = regmap_write ( regmap , reg , data ) ;
2013-10-16 03:07:20 +04:00
break ;
2018-05-14 14:59:51 +03:00
case PX30 :
2017-03-17 20:18:36 +03:00
case RV1108 :
2013-10-16 03:07:20 +04:00
case RK3188 :
2014-07-20 03:49:17 +04:00
case RK3288 :
2019-10-15 12:17:08 +03:00
case RK3308 :
2015-06-13 00:51:01 +03:00
case RK3368 :
2016-02-01 05:58:21 +03:00
case RK3399 :
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
pull_type = bank - > pull_type [ pin_num / 8 ] ;
ret = - EINVAL ;
for ( i = 0 ; i < ARRAY_SIZE ( rockchip_pull_list [ pull_type ] ) ;
i + + ) {
if ( rockchip_pull_list [ pull_type ] [ i ] = = pull ) {
ret = i ;
break ;
}
}
if ( ret < 0 ) {
dev_err ( info - > dev , " unsupported pull setting %d \n " ,
pull ) ;
return ret ;
}
2013-10-16 03:08:42 +04:00
/* enable the write to the equivalent lower bits */
data = ( ( 1 < < RK3188_PULL_BITS_PER_PIN ) - 1 ) < < ( bit + 16 ) ;
2014-08-01 09:58:00 +04:00
rmask = data | ( data > > 16 ) ;
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
data | = ( ret < < bit ) ;
2013-10-16 03:08:42 +04:00
2014-08-01 09:58:00 +04:00
ret = regmap_update_bits ( regmap , reg , rmask , data ) ;
2013-10-16 03:08:42 +04:00
break ;
2013-10-16 03:07:20 +04:00
default :
dev_err ( info - > dev , " unsupported pinctrl type \n " ) ;
return - EINVAL ;
2013-06-11 00:16:22 +04:00
}
2014-05-05 15:58:20 +04:00
return ret ;
2013-06-11 00:16:22 +04:00
}
2017-03-02 10:11:24 +03:00
# define RK3328_SCHMITT_BITS_PER_PIN 1
# define RK3328_SCHMITT_PINS_PER_REG 16
# define RK3328_SCHMITT_BANK_STRIDE 8
# define RK3328_SCHMITT_GRF_OFFSET 0x380
static int rk3328_calc_schmitt_reg_and_bit ( struct rockchip_pin_bank * bank ,
int pin_num ,
struct regmap * * regmap ,
int * reg , u8 * bit )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
* regmap = info - > regmap_base ;
* reg = RK3328_SCHMITT_GRF_OFFSET ;
* reg + = bank - > bank_num * RK3328_SCHMITT_BANK_STRIDE ;
* reg + = ( ( pin_num / RK3328_SCHMITT_PINS_PER_REG ) * 4 ) ;
* bit = pin_num % RK3328_SCHMITT_PINS_PER_REG ;
return 0 ;
}
2017-03-02 10:11:23 +03:00
static int rockchip_get_schmitt ( struct rockchip_pin_bank * bank , int pin_num )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
struct regmap * regmap ;
int reg , ret ;
u8 bit ;
u32 data ;
ret = ctrl - > schmitt_calc_reg ( bank , pin_num , & regmap , & reg , & bit ) ;
if ( ret )
return ret ;
ret = regmap_read ( regmap , reg , & data ) ;
if ( ret )
return ret ;
data > > = bit ;
return data & 0x1 ;
}
static int rockchip_set_schmitt ( struct rockchip_pin_bank * bank ,
int pin_num , int enable )
{
struct rockchip_pinctrl * info = bank - > drvdata ;
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
struct regmap * regmap ;
int reg , ret ;
u8 bit ;
u32 data , rmask ;
dev_dbg ( info - > dev , " setting input schmitt of GPIO%d-%d to %d \n " ,
bank - > bank_num , pin_num , enable ) ;
ret = ctrl - > schmitt_calc_reg ( bank , pin_num , & regmap , & reg , & bit ) ;
if ( ret )
return ret ;
/* enable the write to the equivalent lower bits */
data = BIT ( bit + 16 ) | ( enable < < bit ) ;
rmask = BIT ( bit + 16 ) | BIT ( bit ) ;
2017-03-23 13:59:28 +03:00
return regmap_update_bits ( regmap , reg , rmask , data ) ;
2017-03-02 10:11:23 +03:00
}
2013-06-11 00:16:22 +04:00
/*
* Pinmux_ops handling
*/
static int rockchip_pmx_get_funcs_count ( struct pinctrl_dev * pctldev )
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
return info - > nfunctions ;
}
static const char * rockchip_pmx_get_func_name ( struct pinctrl_dev * pctldev ,
unsigned selector )
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
return info - > functions [ selector ] . name ;
}
static int rockchip_pmx_get_groups ( struct pinctrl_dev * pctldev ,
unsigned selector , const char * const * * groups ,
unsigned * const num_groups )
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
* groups = info - > functions [ selector ] . groups ;
* num_groups = info - > functions [ selector ] . ngroups ;
return 0 ;
}
2014-09-03 15:02:56 +04:00
static int rockchip_pmx_set ( struct pinctrl_dev * pctldev , unsigned selector ,
unsigned group )
2013-06-11 00:16:22 +04:00
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
const unsigned int * pins = info - > groups [ group ] . pins ;
const struct rockchip_pin_config * data = info - > groups [ group ] . data ;
struct rockchip_pin_bank * bank ;
2014-03-26 03:57:00 +04:00
int cnt , ret = 0 ;
2013-06-11 00:16:22 +04:00
dev_dbg ( info - > dev , " enable function %s group %s \n " ,
info - > functions [ selector ] . name , info - > groups [ group ] . name ) ;
/*
2017-12-24 00:22:54 +03:00
* for each pin in the pin group selected , program the corresponding
2013-06-11 00:16:22 +04:00
* pin function number in the config register .
*/
for ( cnt = 0 ; cnt < info - > groups [ group ] . npins ; cnt + + ) {
bank = pin_to_bank ( info , pins [ cnt ] ) ;
2014-03-26 03:57:00 +04:00
ret = rockchip_set_mux ( bank , pins [ cnt ] - bank - > pin_base ,
data [ cnt ] . func ) ;
if ( ret )
break ;
}
if ( ret ) {
/* revert the already done pin settings */
for ( cnt - - ; cnt > = 0 ; cnt - - )
rockchip_set_mux ( bank , pins [ cnt ] - bank - > pin_base , 0 ) ;
return ret ;
2013-06-11 00:16:22 +04:00
}
return 0 ;
}
2016-03-15 10:55:45 +03:00
static int rockchip_gpio_get_direction ( struct gpio_chip * chip , unsigned offset )
{
struct rockchip_pin_bank * bank = gpiochip_get_data ( chip ) ;
u32 data ;
2017-12-12 20:43:43 +03:00
int ret ;
2016-03-15 10:55:45 +03:00
2017-12-12 20:43:43 +03:00
ret = clk_enable ( bank - > clk ) ;
if ( ret < 0 ) {
dev_err ( bank - > drvdata - > dev ,
" failed to enable clock for bank %s \n " , bank - > name ) ;
return ret ;
}
2016-03-15 10:55:45 +03:00
data = readl_relaxed ( bank - > reg_base + GPIO_SWPORT_DDR ) ;
2017-12-12 20:43:43 +03:00
clk_disable ( bank - > clk ) ;
2016-03-15 10:55:45 +03:00
2020-02-14 16:57:12 +03:00
if ( data & BIT ( offset ) )
return GPIO_LINE_DIRECTION_OUT ;
return GPIO_LINE_DIRECTION_IN ;
2016-03-15 10:55:45 +03:00
}
2013-06-11 00:16:22 +04:00
/*
* The calls to gpio_direction_output ( ) and gpio_direction_input ( )
* leads to this function call ( via the pinctrl_gpio_direction_ { input | output } ( )
* function called from the gpiolib interface ) .
*/
2014-10-21 21:47:33 +04:00
static int _rockchip_pmx_gpio_set_direction ( struct gpio_chip * chip ,
int pin , bool input )
2013-06-11 00:16:22 +04:00
{
struct rockchip_pin_bank * bank ;
2014-10-21 21:47:33 +04:00
int ret ;
2014-10-21 21:47:35 +04:00
unsigned long flags ;
2013-06-11 00:16:22 +04:00
u32 data ;
2015-12-08 11:39:13 +03:00
bank = gpiochip_get_data ( chip ) ;
2013-06-11 00:16:22 +04:00
2014-03-26 03:57:00 +04:00
ret = rockchip_set_mux ( bank , pin , RK_FUNC_GPIO ) ;
if ( ret < 0 )
return ret ;
2013-06-11 00:16:22 +04:00
2015-08-11 13:12:04 +03:00
clk_enable ( bank - > clk ) ;
2017-03-23 13:59:29 +03:00
raw_spin_lock_irqsave ( & bank - > slock , flags ) ;
2014-10-21 21:47:35 +04:00
2013-06-11 00:16:22 +04:00
data = readl_relaxed ( bank - > reg_base + GPIO_SWPORT_DDR ) ;
/* set bit to 1 for output, 0 for input */
if ( ! input )
data | = BIT ( pin ) ;
else
data & = ~ BIT ( pin ) ;
writel_relaxed ( data , bank - > reg_base + GPIO_SWPORT_DDR ) ;
2017-03-23 13:59:29 +03:00
raw_spin_unlock_irqrestore ( & bank - > slock , flags ) ;
2015-08-11 13:12:04 +03:00
clk_disable ( bank - > clk ) ;
2014-10-21 21:47:35 +04:00
2013-06-11 00:16:22 +04:00
return 0 ;
}
2014-10-21 21:47:33 +04:00
static int rockchip_pmx_gpio_set_direction ( struct pinctrl_dev * pctldev ,
struct pinctrl_gpio_range * range ,
unsigned offset , bool input )
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
struct gpio_chip * chip ;
int pin ;
chip = range - > gc ;
pin = offset - chip - > base ;
dev_dbg ( info - > dev , " gpio_direction for pin %u as %s-%d to %s \n " ,
offset , range - > name , pin , input ? " input " : " output " ) ;
return _rockchip_pmx_gpio_set_direction ( chip , offset - chip - > base ,
input ) ;
}
2013-06-11 00:16:22 +04:00
static const struct pinmux_ops rockchip_pmx_ops = {
. get_functions_count = rockchip_pmx_get_funcs_count ,
. get_function_name = rockchip_pmx_get_func_name ,
. get_function_groups = rockchip_pmx_get_groups ,
2014-09-03 15:02:56 +04:00
. set_mux = rockchip_pmx_set ,
2013-06-11 00:16:22 +04:00
. gpio_set_direction = rockchip_pmx_gpio_set_direction ,
} ;
/*
* Pinconf_ops handling
*/
2013-06-16 19:41:16 +04:00
static bool rockchip_pinconf_pull_valid ( struct rockchip_pin_ctrl * ctrl ,
enum pin_config_param pull )
{
2013-10-16 03:07:20 +04:00
switch ( ctrl - > type ) {
case RK2928 :
2017-07-21 09:27:15 +03:00
case RK3128 :
2013-10-16 03:07:20 +04:00
return ( pull = = PIN_CONFIG_BIAS_PULL_PIN_DEFAULT | |
pull = = PIN_CONFIG_BIAS_DISABLE ) ;
case RK3066B :
2013-06-16 19:41:16 +04:00
return pull ? false : true ;
2018-05-14 14:59:51 +03:00
case PX30 :
2017-03-17 20:18:36 +03:00
case RV1108 :
2013-10-16 03:07:20 +04:00
case RK3188 :
2014-07-20 03:49:17 +04:00
case RK3288 :
2019-10-15 12:17:08 +03:00
case RK3308 :
2015-06-13 00:51:01 +03:00
case RK3368 :
2016-02-01 05:58:21 +03:00
case RK3399 :
2013-10-16 03:07:20 +04:00
return ( pull ! = PIN_CONFIG_BIAS_PULL_PIN_DEFAULT ) ;
2013-06-16 19:41:16 +04:00
}
2013-10-16 03:07:20 +04:00
return false ;
2013-06-16 19:41:16 +04:00
}
2014-10-21 21:47:33 +04:00
static void rockchip_gpio_set ( struct gpio_chip * gc , unsigned offset , int value ) ;
2014-04-23 16:28:59 +04:00
static int rockchip_gpio_get ( struct gpio_chip * gc , unsigned offset ) ;
2013-06-11 00:16:22 +04:00
/* set the pin config settings for a specified pin */
static int rockchip_pinconf_set ( struct pinctrl_dev * pctldev , unsigned int pin ,
2013-08-27 22:32:12 +04:00
unsigned long * configs , unsigned num_configs )
2013-06-11 00:16:22 +04:00
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
struct rockchip_pin_bank * bank = pin_to_bank ( info , pin ) ;
2013-08-27 22:32:12 +04:00
enum pin_config_param param ;
2017-01-23 15:34:32 +03:00
u32 arg ;
2013-08-27 22:32:12 +04:00
int i ;
int rc ;
for ( i = 0 ; i < num_configs ; i + + ) {
param = pinconf_to_config_param ( configs [ i ] ) ;
arg = pinconf_to_config_argument ( configs [ i ] ) ;
switch ( param ) {
case PIN_CONFIG_BIAS_DISABLE :
rc = rockchip_set_pull ( bank , pin - bank - > pin_base ,
param ) ;
if ( rc )
return rc ;
break ;
case PIN_CONFIG_BIAS_PULL_UP :
case PIN_CONFIG_BIAS_PULL_DOWN :
case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT :
2013-10-16 03:08:42 +04:00
case PIN_CONFIG_BIAS_BUS_HOLD :
2013-08-27 22:32:12 +04:00
if ( ! rockchip_pinconf_pull_valid ( info - > ctrl , param ) )
return - ENOTSUPP ;
if ( ! arg )
return - EINVAL ;
rc = rockchip_set_pull ( bank , pin - bank - > pin_base ,
param ) ;
if ( rc )
return rc ;
break ;
2014-04-23 16:28:59 +04:00
case PIN_CONFIG_OUTPUT :
2014-10-21 21:47:33 +04:00
rockchip_gpio_set ( & bank - > gpio_chip ,
pin - bank - > pin_base , arg ) ;
rc = _rockchip_pmx_gpio_set_direction ( & bank - > gpio_chip ,
pin - bank - > pin_base , false ) ;
2014-04-23 16:28:59 +04:00
if ( rc )
return rc ;
break ;
2014-07-20 03:50:11 +04:00
case PIN_CONFIG_DRIVE_STRENGTH :
/* rk3288 is the first with per-pin drive-strength */
2015-06-13 00:50:11 +03:00
if ( ! info - > ctrl - > drv_calc_reg )
2014-07-20 03:50:11 +04:00
return - ENOTSUPP ;
2015-06-13 00:50:11 +03:00
rc = rockchip_set_drive_perpin ( bank ,
pin - bank - > pin_base , arg ) ;
2014-07-20 03:50:11 +04:00
if ( rc < 0 )
return rc ;
break ;
2017-03-02 10:11:23 +03:00
case PIN_CONFIG_INPUT_SCHMITT_ENABLE :
if ( ! info - > ctrl - > schmitt_calc_reg )
return - ENOTSUPP ;
rc = rockchip_set_schmitt ( bank ,
pin - bank - > pin_base , arg ) ;
if ( rc < 0 )
return rc ;
break ;
2013-08-27 22:32:12 +04:00
default :
2013-06-16 19:41:16 +04:00
return - ENOTSUPP ;
2013-08-27 22:32:12 +04:00
break ;
}
} /* for each config */
2013-06-11 00:16:22 +04:00
return 0 ;
}
/* get the pin config settings for a specified pin */
static int rockchip_pinconf_get ( struct pinctrl_dev * pctldev , unsigned int pin ,
unsigned long * config )
{
struct rockchip_pinctrl * info = pinctrl_dev_get_drvdata ( pctldev ) ;
struct rockchip_pin_bank * bank = pin_to_bank ( info , pin ) ;
enum pin_config_param param = pinconf_to_config_param ( * config ) ;
2014-04-23 16:27:51 +04:00
u16 arg ;
2014-04-23 16:28:59 +04:00
int rc ;
2013-06-11 00:16:22 +04:00
switch ( param ) {
case PIN_CONFIG_BIAS_DISABLE :
2013-06-16 19:41:16 +04:00
if ( rockchip_get_pull ( bank , pin - bank - > pin_base ) ! = param )
return - EINVAL ;
2014-04-23 16:27:51 +04:00
arg = 0 ;
2013-06-16 19:41:16 +04:00
break ;
2013-06-11 00:16:22 +04:00
case PIN_CONFIG_BIAS_PULL_UP :
case PIN_CONFIG_BIAS_PULL_DOWN :
case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT :
2013-10-16 03:08:42 +04:00
case PIN_CONFIG_BIAS_BUS_HOLD :
2013-06-16 19:41:16 +04:00
if ( ! rockchip_pinconf_pull_valid ( info - > ctrl , param ) )
return - ENOTSUPP ;
2013-06-11 00:16:22 +04:00
2013-06-16 19:41:16 +04:00
if ( rockchip_get_pull ( bank , pin - bank - > pin_base ) ! = param )
2013-06-11 00:16:22 +04:00
return - EINVAL ;
2014-04-23 16:27:51 +04:00
arg = 1 ;
2013-06-11 00:16:22 +04:00
break ;
2014-04-23 16:28:59 +04:00
case PIN_CONFIG_OUTPUT :
rc = rockchip_get_mux ( bank , pin - bank - > pin_base ) ;
if ( rc ! = RK_FUNC_GPIO )
return - EINVAL ;
rc = rockchip_gpio_get ( & bank - > gpio_chip , pin - bank - > pin_base ) ;
if ( rc < 0 )
return rc ;
arg = rc ? 1 : 0 ;
break ;
2014-07-20 03:50:11 +04:00
case PIN_CONFIG_DRIVE_STRENGTH :
/* rk3288 is the first with per-pin drive-strength */
2015-06-13 00:50:11 +03:00
if ( ! info - > ctrl - > drv_calc_reg )
2014-07-20 03:50:11 +04:00
return - ENOTSUPP ;
2015-06-13 00:50:11 +03:00
rc = rockchip_get_drive_perpin ( bank , pin - bank - > pin_base ) ;
2014-07-20 03:50:11 +04:00
if ( rc < 0 )
return rc ;
2017-03-02 10:11:23 +03:00
arg = rc ;
break ;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE :
if ( ! info - > ctrl - > schmitt_calc_reg )
return - ENOTSUPP ;
rc = rockchip_get_schmitt ( bank , pin - bank - > pin_base ) ;
if ( rc < 0 )
return rc ;
2014-07-20 03:50:11 +04:00
arg = rc ;
break ;
2013-06-11 00:16:22 +04:00
default :
return - ENOTSUPP ;
break ;
}
2014-04-23 16:27:51 +04:00
* config = pinconf_to_config_packed ( param , arg ) ;
2013-06-11 00:16:22 +04:00
return 0 ;
}
static const struct pinconf_ops rockchip_pinconf_ops = {
. pin_config_get = rockchip_pinconf_get ,
. pin_config_set = rockchip_pinconf_set ,
2014-07-20 03:48:45 +04:00
. is_generic = true ,
2013-06-11 00:16:22 +04:00
} ;
2013-10-16 03:07:49 +04:00
static const struct of_device_id rockchip_bank_match [ ] = {
{ . compatible = " rockchip,gpio-bank " } ,
2013-10-16 03:08:42 +04:00
{ . compatible = " rockchip,rk3188-gpio-bank0 " } ,
2013-10-16 03:07:49 +04:00
{ } ,
} ;
2013-06-11 00:16:22 +04:00
static void rockchip_pinctrl_child_count ( struct rockchip_pinctrl * info ,
struct device_node * np )
{
struct device_node * child ;
for_each_child_of_node ( np , child ) {
2013-10-16 03:07:49 +04:00
if ( of_match_node ( rockchip_bank_match , child ) )
2013-06-11 00:16:22 +04:00
continue ;
info - > nfunctions + + ;
info - > ngroups + = of_get_child_count ( child ) ;
}
}
static int rockchip_pinctrl_parse_groups ( struct device_node * np ,
struct rockchip_pin_group * grp ,
struct rockchip_pinctrl * info ,
u32 index )
{
struct rockchip_pin_bank * bank ;
int size ;
const __be32 * list ;
int num ;
int i , j ;
int ret ;
2018-08-28 04:52:41 +03:00
dev_dbg ( info - > dev , " group(%d): %pOFn \n " , index , np ) ;
2013-06-11 00:16:22 +04:00
/* Initialise group */
grp - > name = np - > name ;
/*
* the binding format is rockchip , pins = < bank pin mux CONFIG > ,
* do sanity check and calculate pins number
*/
list = of_get_property ( np , " rockchip,pins " , & size ) ;
/* we do not check return since it's safe node passed down */
size / = sizeof ( * list ) ;
if ( ! size | | size % 4 ) {
dev_err ( info - > dev , " wrong pins number or pins and configs should be by 4 \n " ) ;
return - EINVAL ;
}
grp - > npins = size / 4 ;
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
grp - > pins = devm_kcalloc ( info - > dev , grp - > npins , sizeof ( unsigned int ) ,
2013-06-11 00:16:22 +04:00
GFP_KERNEL ) ;
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
grp - > data = devm_kcalloc ( info - > dev ,
grp - > npins ,
sizeof ( struct rockchip_pin_config ) ,
2013-06-11 00:16:22 +04:00
GFP_KERNEL ) ;
if ( ! grp - > pins | | ! grp - > data )
return - ENOMEM ;
for ( i = 0 , j = 0 ; i < size ; i + = 4 , j + + ) {
const __be32 * phandle ;
struct device_node * np_config ;
num = be32_to_cpu ( * list + + ) ;
bank = bank_num_to_bank ( info , num ) ;
if ( IS_ERR ( bank ) )
return PTR_ERR ( bank ) ;
grp - > pins [ j ] = bank - > pin_base + be32_to_cpu ( * list + + ) ;
grp - > data [ j ] . func = be32_to_cpu ( * list + + ) ;
phandle = list + + ;
if ( ! phandle )
return - EINVAL ;
np_config = of_find_node_by_phandle ( be32_to_cpup ( phandle ) ) ;
2015-01-09 18:43:46 +03:00
ret = pinconf_generic_parse_dt_config ( np_config , NULL ,
2013-06-11 00:16:22 +04:00
& grp - > data [ j ] . configs , & grp - > data [ j ] . nconfigs ) ;
if ( ret )
return ret ;
}
return 0 ;
}
static int rockchip_pinctrl_parse_functions ( struct device_node * np ,
struct rockchip_pinctrl * info ,
u32 index )
{
struct device_node * child ;
struct rockchip_pmx_func * func ;
struct rockchip_pin_group * grp ;
int ret ;
static u32 grp_index ;
u32 i = 0 ;
2018-08-28 04:52:41 +03:00
dev_dbg ( info - > dev , " parse function(%d): %pOFn \n " , index , np ) ;
2013-06-11 00:16:22 +04:00
func = & info - > functions [ index ] ;
/* Initialise function */
func - > name = np - > name ;
func - > ngroups = of_get_child_count ( np ) ;
if ( func - > ngroups < = 0 )
return 0 ;
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
func - > groups = devm_kcalloc ( info - > dev ,
func - > ngroups , sizeof ( char * ) , GFP_KERNEL ) ;
2013-06-11 00:16:22 +04:00
if ( ! func - > groups )
return - ENOMEM ;
for_each_child_of_node ( np , child ) {
func - > groups [ i ] = child - > name ;
grp = & info - > groups [ grp_index + + ] ;
ret = rockchip_pinctrl_parse_groups ( child , grp , info , i + + ) ;
2015-12-21 19:39:47 +03:00
if ( ret ) {
of_node_put ( child ) ;
2013-06-11 00:16:22 +04:00
return ret ;
2015-12-21 19:39:47 +03:00
}
2013-06-11 00:16:22 +04:00
}
return 0 ;
}
static int rockchip_pinctrl_parse_dt ( struct platform_device * pdev ,
struct rockchip_pinctrl * info )
{
struct device * dev = & pdev - > dev ;
struct device_node * np = dev - > of_node ;
struct device_node * child ;
int ret ;
int i ;
rockchip_pinctrl_child_count ( info , np ) ;
dev_dbg ( & pdev - > dev , " nfunctions = %d \n " , info - > nfunctions ) ;
dev_dbg ( & pdev - > dev , " ngroups = %d \n " , info - > ngroups ) ;
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
info - > functions = devm_kcalloc ( dev ,
info - > nfunctions ,
2013-06-11 00:16:22 +04:00
sizeof ( struct rockchip_pmx_func ) ,
GFP_KERNEL ) ;
2017-12-24 00:02:47 +03:00
if ( ! info - > functions )
2020-05-06 13:14:24 +03:00
return - ENOMEM ;
2013-06-11 00:16:22 +04:00
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
info - > groups = devm_kcalloc ( dev ,
info - > ngroups ,
2013-06-11 00:16:22 +04:00
sizeof ( struct rockchip_pin_group ) ,
GFP_KERNEL ) ;
2017-12-24 00:02:47 +03:00
if ( ! info - > groups )
2020-05-06 13:14:24 +03:00
return - ENOMEM ;
2013-06-11 00:16:22 +04:00
i = 0 ;
for_each_child_of_node ( np , child ) {
2013-10-16 03:07:49 +04:00
if ( of_match_node ( rockchip_bank_match , child ) )
2013-06-11 00:16:22 +04:00
continue ;
2013-10-16 03:07:49 +04:00
2013-06-11 00:16:22 +04:00
ret = rockchip_pinctrl_parse_functions ( child , info , i + + ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " failed to parse function \n " ) ;
2015-12-21 19:39:47 +03:00
of_node_put ( child ) ;
2013-06-11 00:16:22 +04:00
return ret ;
}
}
return 0 ;
}
static int rockchip_pinctrl_register ( struct platform_device * pdev ,
struct rockchip_pinctrl * info )
{
struct pinctrl_desc * ctrldesc = & info - > pctl ;
struct pinctrl_pin_desc * pindesc , * pdesc ;
struct rockchip_pin_bank * pin_bank ;
int pin , bank , ret ;
int k ;
ctrldesc - > name = " rockchip-pinctrl " ;
ctrldesc - > owner = THIS_MODULE ;
ctrldesc - > pctlops = & rockchip_pctrl_ops ;
ctrldesc - > pmxops = & rockchip_pmx_ops ;
ctrldesc - > confops = & rockchip_pinconf_ops ;
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
pindesc = devm_kcalloc ( & pdev - > dev ,
info - > ctrl - > nr_pins , sizeof ( * pindesc ) ,
GFP_KERNEL ) ;
2017-12-24 00:02:47 +03:00
if ( ! pindesc )
2013-06-11 00:16:22 +04:00
return - ENOMEM ;
2017-12-24 00:02:47 +03:00
2013-06-11 00:16:22 +04:00
ctrldesc - > pins = pindesc ;
ctrldesc - > npins = info - > ctrl - > nr_pins ;
pdesc = pindesc ;
for ( bank = 0 , k = 0 ; bank < info - > ctrl - > nr_banks ; bank + + ) {
pin_bank = & info - > ctrl - > pin_banks [ bank ] ;
for ( pin = 0 ; pin < pin_bank - > nr_pins ; pin + + , k + + ) {
pdesc - > number = k ;
pdesc - > name = kasprintf ( GFP_KERNEL , " %s-%d " ,
pin_bank - > name , pin ) ;
pdesc + + ;
}
}
2014-10-21 21:47:34 +04:00
ret = rockchip_pinctrl_parse_dt ( pdev , info ) ;
if ( ret )
return ret ;
2016-02-24 12:14:07 +03:00
info - > pctl_dev = devm_pinctrl_register ( & pdev - > dev , ctrldesc , info ) ;
2015-06-09 07:01:16 +03:00
if ( IS_ERR ( info - > pctl_dev ) ) {
2013-06-11 00:16:22 +04:00
dev_err ( & pdev - > dev , " could not register pinctrl driver \n " ) ;
2015-06-09 07:01:16 +03:00
return PTR_ERR ( info - > pctl_dev ) ;
2013-06-11 00:16:22 +04:00
}
for ( bank = 0 ; bank < info - > ctrl - > nr_banks ; + + bank ) {
pin_bank = & info - > ctrl - > pin_banks [ bank ] ;
pin_bank - > grange . name = pin_bank - > name ;
pin_bank - > grange . id = bank ;
pin_bank - > grange . pin_base = pin_bank - > pin_base ;
pin_bank - > grange . base = pin_bank - > gpio_chip . base ;
pin_bank - > grange . npins = pin_bank - > gpio_chip . ngpio ;
pin_bank - > grange . gc = & pin_bank - > gpio_chip ;
pinctrl_add_gpio_range ( info - > pctl_dev , & pin_bank - > grange ) ;
}
return 0 ;
}
/*
* GPIO handling
*/
static void rockchip_gpio_set ( struct gpio_chip * gc , unsigned offset , int value )
{
2015-12-08 11:39:13 +03:00
struct rockchip_pin_bank * bank = gpiochip_get_data ( gc ) ;
2013-06-11 00:16:22 +04:00
void __iomem * reg = bank - > reg_base + GPIO_SWPORT_DR ;
unsigned long flags ;
u32 data ;
2015-08-11 13:12:04 +03:00
clk_enable ( bank - > clk ) ;
2017-03-23 13:59:29 +03:00
raw_spin_lock_irqsave ( & bank - > slock , flags ) ;
2013-06-11 00:16:22 +04:00
data = readl ( reg ) ;
data & = ~ BIT ( offset ) ;
if ( value )
data | = BIT ( offset ) ;
writel ( data , reg ) ;
2017-03-23 13:59:29 +03:00
raw_spin_unlock_irqrestore ( & bank - > slock , flags ) ;
2015-08-11 13:12:04 +03:00
clk_disable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
}
/*
* Returns the level of the pin for input direction and setting of the DR
* register for output gpios .
*/
static int rockchip_gpio_get ( struct gpio_chip * gc , unsigned offset )
{
2015-12-08 11:39:13 +03:00
struct rockchip_pin_bank * bank = gpiochip_get_data ( gc ) ;
2013-06-11 00:16:22 +04:00
u32 data ;
2015-08-11 13:12:04 +03:00
clk_enable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
data = readl ( bank - > reg_base + GPIO_EXT_PORT ) ;
2015-08-11 13:12:04 +03:00
clk_disable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
data > > = offset ;
data & = 1 ;
return data ;
}
/*
* gpiolib gpio_direction_input callback function . The setting of the pin
2017-12-24 00:22:54 +03:00
* mux function as ' gpio input ' will be handled by the pinctrl subsystem
2013-06-11 00:16:22 +04:00
* interface .
*/
static int rockchip_gpio_direction_input ( struct gpio_chip * gc , unsigned offset )
{
return pinctrl_gpio_direction_input ( gc - > base + offset ) ;
}
/*
* gpiolib gpio_direction_output callback function . The setting of the pin
2017-12-24 00:22:54 +03:00
* mux function as ' gpio output ' will be handled by the pinctrl subsystem
2013-06-11 00:16:22 +04:00
* interface .
*/
static int rockchip_gpio_direction_output ( struct gpio_chip * gc ,
unsigned offset , int value )
{
rockchip_gpio_set ( gc , offset , value ) ;
return pinctrl_gpio_direction_output ( gc - > base + offset ) ;
}
2018-05-03 11:04:42 +03:00
static void rockchip_gpio_set_debounce ( struct gpio_chip * gc ,
unsigned int offset , bool enable )
{
struct rockchip_pin_bank * bank = gpiochip_get_data ( gc ) ;
void __iomem * reg = bank - > reg_base + GPIO_DEBOUNCE ;
unsigned long flags ;
u32 data ;
clk_enable ( bank - > clk ) ;
raw_spin_lock_irqsave ( & bank - > slock , flags ) ;
data = readl ( reg ) ;
if ( enable )
data | = BIT ( offset ) ;
else
data & = ~ BIT ( offset ) ;
writel ( data , reg ) ;
raw_spin_unlock_irqrestore ( & bank - > slock , flags ) ;
clk_disable ( bank - > clk ) ;
}
/*
* gpiolib set_config callback function . The setting of the pin
* mux function as ' gpio output ' will be handled by the pinctrl subsystem
* interface .
*/
static int rockchip_gpio_set_config ( struct gpio_chip * gc , unsigned int offset ,
unsigned long config )
{
enum pin_config_param param = pinconf_to_config_param ( config ) ;
switch ( param ) {
case PIN_CONFIG_INPUT_DEBOUNCE :
rockchip_gpio_set_debounce ( gc , offset , true ) ;
/*
* Rockchip ' s gpio could only support up to one period
* of the debounce clock ( pclk ) , which is far away from
* satisftying the requirement , as pclk is usually near
* 100 MHz shared by all peripherals . So the fact is it
* has crippled debounce capability could only be useful
* to prevent any spurious glitches from waking up the system
* if the gpio is conguired as wakeup interrupt source . Let ' s
* still return - ENOTSUPP as before , to make sure the caller
* of gpiod_set_debounce won ' t change its behaviour .
*/
2019-07-26 14:28:12 +03:00
return - ENOTSUPP ;
2018-05-03 11:04:42 +03:00
default :
return - ENOTSUPP ;
}
}
2013-06-11 00:16:22 +04:00
/*
* gpiolib gpio_to_irq callback function . Creates a mapping between a GPIO pin
* and a virtual IRQ , if not already present .
*/
static int rockchip_gpio_to_irq ( struct gpio_chip * gc , unsigned offset )
{
2015-12-08 11:39:13 +03:00
struct rockchip_pin_bank * bank = gpiochip_get_data ( gc ) ;
2013-06-11 00:16:22 +04:00
unsigned int virq ;
if ( ! bank - > domain )
return - ENXIO ;
2020-10-13 09:37:30 +03:00
clk_enable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
virq = irq_create_mapping ( bank - > domain , offset ) ;
2020-10-13 09:37:30 +03:00
clk_disable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
return ( virq ) ? : - ENXIO ;
}
static const struct gpio_chip rockchip_gpiolib_chip = {
2015-10-11 18:34:19 +03:00
. request = gpiochip_generic_request ,
. free = gpiochip_generic_free ,
2013-06-11 00:16:22 +04:00
. set = rockchip_gpio_set ,
. get = rockchip_gpio_get ,
2016-03-15 10:55:45 +03:00
. get_direction = rockchip_gpio_get_direction ,
2013-06-11 00:16:22 +04:00
. direction_input = rockchip_gpio_direction_input ,
. direction_output = rockchip_gpio_direction_output ,
2018-05-03 11:04:42 +03:00
. set_config = rockchip_gpio_set_config ,
2013-06-11 00:16:22 +04:00
. to_irq = rockchip_gpio_to_irq ,
. owner = THIS_MODULE ,
} ;
/*
* Interrupt handling
*/
2015-09-14 11:42:37 +03:00
static void rockchip_irq_demux ( struct irq_desc * desc )
2013-06-11 00:16:22 +04:00
{
2015-06-04 07:13:16 +03:00
struct irq_chip * chip = irq_desc_get_chip ( desc ) ;
struct rockchip_pin_bank * bank = irq_desc_get_handler_data ( desc ) ;
2013-06-11 00:16:22 +04:00
u32 pend ;
dev_dbg ( bank - > drvdata - > dev , " got irq for bank %s \n " , bank - > name ) ;
chained_irq_enter ( chip , desc ) ;
pend = readl_relaxed ( bank - > reg_base + GPIO_INT_STATUS ) ;
while ( pend ) {
2015-07-13 02:52:00 +03:00
unsigned int irq , virq ;
2013-06-11 00:16:22 +04:00
irq = __ffs ( pend ) ;
pend & = ~ BIT ( irq ) ;
2020-10-13 09:37:31 +03:00
virq = irq_find_mapping ( bank - > domain , irq ) ;
2013-06-11 00:16:22 +04:00
if ( ! virq ) {
dev_err ( bank - > drvdata - > dev , " unmapped irq %d \n " , irq ) ;
continue ;
}
dev_dbg ( bank - > drvdata - > dev , " handling irq %d \n " , irq ) ;
2013-10-16 03:09:08 +04:00
/*
* Triggering IRQ on both rising and falling edge
* needs manual intervention .
*/
if ( bank - > toggle_edge_mode & BIT ( irq ) ) {
2014-12-22 21:47:29 +03:00
u32 data , data_old , polarity ;
unsigned long flags ;
data = readl_relaxed ( bank - > reg_base + GPIO_EXT_PORT ) ;
do {
2017-03-23 13:59:29 +03:00
raw_spin_lock_irqsave ( & bank - > slock , flags ) ;
2014-12-22 21:47:29 +03:00
polarity = readl_relaxed ( bank - > reg_base +
GPIO_INT_POLARITY ) ;
if ( data & BIT ( irq ) )
polarity & = ~ BIT ( irq ) ;
else
polarity | = BIT ( irq ) ;
writel ( polarity ,
bank - > reg_base + GPIO_INT_POLARITY ) ;
2017-03-23 13:59:29 +03:00
raw_spin_unlock_irqrestore ( & bank - > slock , flags ) ;
2014-12-22 21:47:29 +03:00
data_old = data ;
data = readl_relaxed ( bank - > reg_base +
GPIO_EXT_PORT ) ;
} while ( ( data & BIT ( irq ) ) ! = ( data_old & BIT ( irq ) ) ) ;
2013-10-16 03:09:08 +04:00
}
2013-06-11 00:16:22 +04:00
generic_handle_irq ( virq ) ;
}
chained_irq_exit ( chip , desc ) ;
}
static int rockchip_irq_set_type ( struct irq_data * d , unsigned int type )
{
struct irq_chip_generic * gc = irq_data_get_irq_chip_data ( d ) ;
struct rockchip_pin_bank * bank = gc - > private ;
u32 mask = BIT ( d - > hwirq ) ;
u32 polarity ;
u32 level ;
u32 data ;
2014-10-21 21:47:35 +04:00
unsigned long flags ;
2014-03-26 03:57:00 +04:00
int ret ;
2013-06-11 00:16:22 +04:00
2013-10-16 03:09:08 +04:00
/* make sure the pin is configured as gpio input */
2017-06-23 23:59:11 +03:00
ret = rockchip_set_mux ( bank , d - > hwirq , RK_FUNC_GPIO ) ;
2014-03-26 03:57:00 +04:00
if ( ret < 0 )
return ret ;
2017-06-23 23:59:11 +03:00
clk_enable ( bank - > clk ) ;
2017-03-23 13:59:29 +03:00
raw_spin_lock_irqsave ( & bank - > slock , flags ) ;
2014-10-21 21:47:35 +04:00
2013-10-16 03:09:08 +04:00
data = readl_relaxed ( bank - > reg_base + GPIO_SWPORT_DDR ) ;
data & = ~ mask ;
writel_relaxed ( data , bank - > reg_base + GPIO_SWPORT_DDR ) ;
2017-03-23 13:59:29 +03:00
raw_spin_unlock_irqrestore ( & bank - > slock , flags ) ;
2014-10-21 21:47:35 +04:00
2013-06-11 00:16:22 +04:00
if ( type & IRQ_TYPE_EDGE_BOTH )
2015-06-23 16:52:50 +03:00
irq_set_handler_locked ( d , handle_edge_irq ) ;
2013-06-11 00:16:22 +04:00
else
2015-06-23 16:52:50 +03:00
irq_set_handler_locked ( d , handle_level_irq ) ;
2013-06-11 00:16:22 +04:00
2017-03-23 13:59:29 +03:00
raw_spin_lock_irqsave ( & bank - > slock , flags ) ;
2013-06-11 00:16:22 +04:00
irq_gc_lock ( gc ) ;
level = readl_relaxed ( gc - > reg_base + GPIO_INTTYPE_LEVEL ) ;
polarity = readl_relaxed ( gc - > reg_base + GPIO_INT_POLARITY ) ;
switch ( type ) {
2013-10-16 03:09:08 +04:00
case IRQ_TYPE_EDGE_BOTH :
bank - > toggle_edge_mode | = mask ;
level | = mask ;
/*
* Determine gpio state . If 1 next interrupt should be falling
* otherwise rising .
*/
data = readl ( bank - > reg_base + GPIO_EXT_PORT ) ;
if ( data & mask )
polarity & = ~ mask ;
else
polarity | = mask ;
break ;
2013-06-11 00:16:22 +04:00
case IRQ_TYPE_EDGE_RISING :
2013-10-16 03:09:08 +04:00
bank - > toggle_edge_mode & = ~ mask ;
2013-06-11 00:16:22 +04:00
level | = mask ;
polarity | = mask ;
break ;
case IRQ_TYPE_EDGE_FALLING :
2013-10-16 03:09:08 +04:00
bank - > toggle_edge_mode & = ~ mask ;
2013-06-11 00:16:22 +04:00
level | = mask ;
polarity & = ~ mask ;
break ;
case IRQ_TYPE_LEVEL_HIGH :
2013-10-16 03:09:08 +04:00
bank - > toggle_edge_mode & = ~ mask ;
2013-06-11 00:16:22 +04:00
level & = ~ mask ;
polarity | = mask ;
break ;
case IRQ_TYPE_LEVEL_LOW :
2013-10-16 03:09:08 +04:00
bank - > toggle_edge_mode & = ~ mask ;
2013-06-11 00:16:22 +04:00
level & = ~ mask ;
polarity & = ~ mask ;
break ;
default :
2013-06-23 04:48:34 +04:00
irq_gc_unlock ( gc ) ;
2017-03-23 13:59:29 +03:00
raw_spin_unlock_irqrestore ( & bank - > slock , flags ) ;
2017-06-23 23:59:11 +03:00
clk_disable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
return - EINVAL ;
}
writel_relaxed ( level , gc - > reg_base + GPIO_INTTYPE_LEVEL ) ;
writel_relaxed ( polarity , gc - > reg_base + GPIO_INT_POLARITY ) ;
irq_gc_unlock ( gc ) ;
2017-03-23 13:59:29 +03:00
raw_spin_unlock_irqrestore ( & bank - > slock , flags ) ;
2017-06-23 23:59:11 +03:00
clk_disable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
return 0 ;
}
2014-11-20 01:51:32 +03:00
static void rockchip_irq_suspend ( struct irq_data * d )
{
struct irq_chip_generic * gc = irq_data_get_irq_chip_data ( d ) ;
struct rockchip_pin_bank * bank = gc - > private ;
2015-08-11 13:12:04 +03:00
clk_enable ( bank - > clk ) ;
2015-01-26 19:24:03 +03:00
bank - > saved_masks = irq_reg_readl ( gc , GPIO_INTMASK ) ;
irq_reg_writel ( gc , ~ gc - > wake_active , GPIO_INTMASK ) ;
2015-08-11 13:12:04 +03:00
clk_disable ( bank - > clk ) ;
2014-11-20 01:51:32 +03:00
}
static void rockchip_irq_resume ( struct irq_data * d )
{
struct irq_chip_generic * gc = irq_data_get_irq_chip_data ( d ) ;
struct rockchip_pin_bank * bank = gc - > private ;
2015-08-11 13:12:04 +03:00
clk_enable ( bank - > clk ) ;
2015-01-26 19:24:03 +03:00
irq_reg_writel ( gc , bank - > saved_masks , GPIO_INTMASK ) ;
2015-08-11 13:12:04 +03:00
clk_disable ( bank - > clk ) ;
}
2017-03-02 08:56:52 +03:00
static void rockchip_irq_enable ( struct irq_data * d )
2015-08-11 13:12:04 +03:00
{
struct irq_chip_generic * gc = irq_data_get_irq_chip_data ( d ) ;
struct rockchip_pin_bank * bank = gc - > private ;
clk_enable ( bank - > clk ) ;
irq_gc_mask_clr_bit ( d ) ;
}
2017-03-02 08:56:52 +03:00
static void rockchip_irq_disable ( struct irq_data * d )
2015-08-11 13:12:04 +03:00
{
struct irq_chip_generic * gc = irq_data_get_irq_chip_data ( d ) ;
struct rockchip_pin_bank * bank = gc - > private ;
irq_gc_mask_set_bit ( d ) ;
clk_disable ( bank - > clk ) ;
2014-11-20 01:51:33 +03:00
}
2013-06-11 00:16:22 +04:00
static int rockchip_interrupts_register ( struct platform_device * pdev ,
struct rockchip_pinctrl * info )
{
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
struct rockchip_pin_bank * bank = ctrl - > pin_banks ;
unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN ;
struct irq_chip_generic * gc ;
int ret ;
2020-10-13 09:37:31 +03:00
int i ;
2013-06-11 00:16:22 +04:00
for ( i = 0 ; i < ctrl - > nr_banks ; + + i , + + bank ) {
if ( ! bank - > valid ) {
dev_warn ( & pdev - > dev , " bank %s is not valid \n " ,
bank - > name ) ;
continue ;
}
2015-08-11 13:12:04 +03:00
ret = clk_enable ( bank - > clk ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " failed to enable clock for bank %s \n " ,
bank - > name ) ;
continue ;
}
2013-06-11 00:16:22 +04:00
bank - > domain = irq_domain_add_linear ( bank - > of_node , 32 ,
& irq_generic_chip_ops , NULL ) ;
if ( ! bank - > domain ) {
dev_warn ( & pdev - > dev , " could not initialize irq domain for bank %s \n " ,
bank - > name ) ;
2015-08-11 13:12:04 +03:00
clk_disable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
continue ;
}
ret = irq_alloc_domain_generic_chips ( bank - > domain , 32 , 1 ,
" rockchip_gpio_irq " , handle_level_irq ,
2020-10-13 09:37:31 +03:00
clr , 0 , 0 ) ;
2013-06-11 00:16:22 +04:00
if ( ret ) {
dev_err ( & pdev - > dev , " could not alloc generic chips for bank %s \n " ,
bank - > name ) ;
irq_domain_remove ( bank - > domain ) ;
2015-08-11 13:12:04 +03:00
clk_disable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
continue ;
}
gc = irq_get_domain_generic_chip ( bank - > domain , 0 ) ;
gc - > reg_base = bank - > reg_base ;
gc - > private = bank ;
2014-11-20 01:51:33 +03:00
gc - > chip_types [ 0 ] . regs . mask = GPIO_INTMASK ;
2013-06-11 00:16:22 +04:00
gc - > chip_types [ 0 ] . regs . ack = GPIO_PORTS_EOI ;
gc - > chip_types [ 0 ] . chip . irq_ack = irq_gc_ack_set_bit ;
2017-03-02 08:56:52 +03:00
gc - > chip_types [ 0 ] . chip . irq_mask = irq_gc_mask_set_bit ;
gc - > chip_types [ 0 ] . chip . irq_unmask = irq_gc_mask_clr_bit ;
gc - > chip_types [ 0 ] . chip . irq_enable = rockchip_irq_enable ;
gc - > chip_types [ 0 ] . chip . irq_disable = rockchip_irq_disable ;
2013-06-11 00:16:22 +04:00
gc - > chip_types [ 0 ] . chip . irq_set_wake = irq_gc_set_wake ;
2014-11-20 01:51:32 +03:00
gc - > chip_types [ 0 ] . chip . irq_suspend = rockchip_irq_suspend ;
gc - > chip_types [ 0 ] . chip . irq_resume = rockchip_irq_resume ;
2013-06-11 00:16:22 +04:00
gc - > chip_types [ 0 ] . chip . irq_set_type = rockchip_irq_set_type ;
2014-10-21 21:47:32 +04:00
gc - > wake_enabled = IRQ_MSK ( bank - > nr_pins ) ;
2013-06-11 00:16:22 +04:00
2020-10-13 09:37:31 +03:00
/*
* Linux assumes that all interrupts start out disabled / masked .
* Our driver only uses the concept of masked and always keeps
* things enabled , so for us that ' s all masked and all enabled .
*/
writel_relaxed ( 0xffffffff , bank - > reg_base + GPIO_INTMASK ) ;
2021-02-23 13:19:37 +03:00
writel_relaxed ( 0xffffffff , bank - > reg_base + GPIO_PORTS_EOI ) ;
2020-10-13 09:37:31 +03:00
writel_relaxed ( 0xffffffff , bank - > reg_base + GPIO_INTEN ) ;
gc - > mask_cache = 0xffffffff ;
2015-06-21 22:11:06 +03:00
irq_set_chained_handler_and_data ( bank - > irq ,
rockchip_irq_demux , bank ) ;
2015-08-11 13:12:04 +03:00
clk_disable ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
}
return 0 ;
}
static int rockchip_gpiolib_register ( struct platform_device * pdev ,
struct rockchip_pinctrl * info )
{
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
struct rockchip_pin_bank * bank = ctrl - > pin_banks ;
struct gpio_chip * gc ;
int ret ;
int i ;
for ( i = 0 ; i < ctrl - > nr_banks ; + + i , + + bank ) {
if ( ! bank - > valid ) {
dev_warn ( & pdev - > dev , " bank %s is not valid \n " ,
bank - > name ) ;
continue ;
}
bank - > gpio_chip = rockchip_gpiolib_chip ;
gc = & bank - > gpio_chip ;
gc - > base = bank - > pin_base ;
gc - > ngpio = bank - > nr_pins ;
2015-11-04 11:56:26 +03:00
gc - > parent = & pdev - > dev ;
2013-06-11 00:16:22 +04:00
gc - > of_node = bank - > of_node ;
gc - > label = bank - > name ;
2015-12-08 11:39:13 +03:00
ret = gpiochip_add_data ( gc , bank ) ;
2013-06-11 00:16:22 +04:00
if ( ret ) {
dev_err ( & pdev - > dev , " failed to register gpio_chip %s, error code: %d \n " ,
gc - > label , ret ) ;
goto fail ;
}
}
rockchip_interrupts_register ( pdev , info ) ;
return 0 ;
fail :
for ( - - i , - - bank ; i > = 0 ; - - i , - - bank ) {
if ( ! bank - > valid )
continue ;
2014-07-13 00:30:13 +04:00
gpiochip_remove ( & bank - > gpio_chip ) ;
2013-06-11 00:16:22 +04:00
}
return ret ;
}
static int rockchip_gpiolib_unregister ( struct platform_device * pdev ,
struct rockchip_pinctrl * info )
{
struct rockchip_pin_ctrl * ctrl = info - > ctrl ;
struct rockchip_pin_bank * bank = ctrl - > pin_banks ;
int i ;
2014-07-13 00:30:13 +04:00
for ( i = 0 ; i < ctrl - > nr_banks ; + + i , + + bank ) {
2013-06-11 00:16:22 +04:00
if ( ! bank - > valid )
continue ;
2014-07-13 00:30:13 +04:00
gpiochip_remove ( & bank - > gpio_chip ) ;
2013-06-11 00:16:22 +04:00
}
2014-07-13 00:30:13 +04:00
return 0 ;
2013-06-11 00:16:22 +04:00
}
static int rockchip_get_bank_data ( struct rockchip_pin_bank * bank ,
2014-05-05 15:58:46 +04:00
struct rockchip_pinctrl * info )
2013-06-11 00:16:22 +04:00
{
struct resource res ;
2014-05-05 15:58:20 +04:00
void __iomem * base ;
2013-06-11 00:16:22 +04:00
if ( of_address_to_resource ( bank - > of_node , 0 , & res ) ) {
2014-05-05 15:58:46 +04:00
dev_err ( info - > dev , " cannot find IO resource for bank \n " ) ;
2013-06-11 00:16:22 +04:00
return - ENOENT ;
}
2014-05-05 15:58:46 +04:00
bank - > reg_base = devm_ioremap_resource ( info - > dev , & res ) ;
2013-06-11 00:16:22 +04:00
if ( IS_ERR ( bank - > reg_base ) )
return PTR_ERR ( bank - > reg_base ) ;
2013-10-16 03:08:42 +04:00
/*
* special case , where parts of the pull setting - registers are
* part of the PMU register space
*/
if ( of_device_is_compatible ( bank - > of_node ,
" rockchip,rk3188-gpio-bank0 " ) ) {
2014-05-05 15:59:30 +04:00
struct device_node * node ;
2014-05-05 15:58:00 +04:00
2014-05-05 15:59:30 +04:00
node = of_parse_phandle ( bank - > of_node - > parent ,
" rockchip,pmu " , 0 ) ;
if ( ! node ) {
if ( of_address_to_resource ( bank - > of_node , 1 , & res ) ) {
dev_err ( info - > dev , " cannot find IO resource for bank \n " ) ;
return - ENOENT ;
}
base = devm_ioremap_resource ( info - > dev , & res ) ;
if ( IS_ERR ( base ) )
return PTR_ERR ( base ) ;
rockchip_regmap_config . max_register =
resource_size ( & res ) - 4 ;
rockchip_regmap_config . name =
" rockchip,rk3188-gpio-bank0-pull " ;
bank - > regmap_pull = devm_regmap_init_mmio ( info - > dev ,
base ,
& rockchip_regmap_config ) ;
2013-10-16 03:08:42 +04:00
}
2019-04-15 09:24:02 +03:00
of_node_put ( node ) ;
2013-10-16 03:08:42 +04:00
}
2013-10-16 03:07:49 +04:00
2013-06-11 00:16:22 +04:00
bank - > irq = irq_of_parse_and_map ( bank - > of_node , 0 ) ;
bank - > clk = of_clk_get ( bank - > of_node , 0 ) ;
if ( IS_ERR ( bank - > clk ) )
return PTR_ERR ( bank - > clk ) ;
2015-08-11 13:12:04 +03:00
return clk_prepare ( bank - > clk ) ;
2013-06-11 00:16:22 +04:00
}
static const struct of_device_id rockchip_pinctrl_dt_match [ ] ;
/* retrieve the soc specific data */
static struct rockchip_pin_ctrl * rockchip_pinctrl_get_soc_data (
struct rockchip_pinctrl * d ,
struct platform_device * pdev )
{
const struct of_device_id * match ;
struct device_node * node = pdev - > dev . of_node ;
struct device_node * np ;
struct rockchip_pin_ctrl * ctrl ;
struct rockchip_pin_bank * bank ;
2016-02-01 05:58:21 +03:00
int grf_offs , pmu_offs , drv_grf_offs , drv_pmu_offs , i , j ;
2013-06-11 00:16:22 +04:00
match = of_match_node ( rockchip_pinctrl_dt_match , node ) ;
ctrl = ( struct rockchip_pin_ctrl * ) match - > data ;
for_each_child_of_node ( node , np ) {
if ( ! of_find_property ( np , " gpio-controller " , NULL ) )
continue ;
bank = ctrl - > pin_banks ;
for ( i = 0 ; i < ctrl - > nr_banks ; + + i , + + bank ) {
if ( ! strcmp ( bank - > name , np - > name ) ) {
bank - > of_node = np ;
2014-05-05 15:58:46 +04:00
if ( ! rockchip_get_bank_data ( bank , d ) )
2013-06-11 00:16:22 +04:00
bank - > valid = true ;
break ;
}
}
}
2014-06-16 03:37:23 +04:00
grf_offs = ctrl - > grf_mux_offset ;
pmu_offs = ctrl - > pmu_mux_offset ;
2016-02-01 05:58:21 +03:00
drv_pmu_offs = ctrl - > pmu_drv_offset ;
drv_grf_offs = ctrl - > grf_drv_offset ;
2013-06-11 00:16:22 +04:00
bank = ctrl - > pin_banks ;
for ( i = 0 ; i < ctrl - > nr_banks ; + + i , + + bank ) {
2014-06-16 03:36:33 +04:00
int bank_pins = 0 ;
2017-03-23 13:59:29 +03:00
raw_spin_lock_init ( & bank - > slock ) ;
2013-06-11 00:16:22 +04:00
bank - > drvdata = d ;
bank - > pin_base = ctrl - > nr_pins ;
ctrl - > nr_pins + = bank - > nr_pins ;
2014-06-16 03:36:33 +04:00
2016-02-01 05:58:21 +03:00
/* calculate iomux and drv offsets */
2014-06-16 03:36:33 +04:00
for ( j = 0 ; j < 4 ; j + + ) {
struct rockchip_iomux * iom = & bank - > iomux [ j ] ;
2016-02-01 05:58:21 +03:00
struct rockchip_drv * drv = & bank - > drv [ j ] ;
2014-06-16 03:36:57 +04:00
int inc ;
2014-06-16 03:36:33 +04:00
if ( bank_pins > = bank - > nr_pins )
break ;
2016-02-01 05:58:21 +03:00
/* preset iomux offset value, set new start value */
2014-06-16 03:36:33 +04:00
if ( iom - > offset > = 0 ) {
2014-06-16 03:37:23 +04:00
if ( iom - > type & IOMUX_SOURCE_PMU )
pmu_offs = iom - > offset ;
else
grf_offs = iom - > offset ;
2016-02-01 05:58:21 +03:00
} else { /* set current iomux offset */
2014-06-16 03:37:23 +04:00
iom - > offset = ( iom - > type & IOMUX_SOURCE_PMU ) ?
pmu_offs : grf_offs ;
2014-06-16 03:36:33 +04:00
}
2016-02-01 05:58:21 +03:00
/* preset drv offset value, set new start value */
if ( drv - > offset > = 0 ) {
if ( iom - > type & IOMUX_SOURCE_PMU )
drv_pmu_offs = drv - > offset ;
else
drv_grf_offs = drv - > offset ;
} else { /* set current drv offset */
drv - > offset = ( iom - > type & IOMUX_SOURCE_PMU ) ?
drv_pmu_offs : drv_grf_offs ;
}
dev_dbg ( d - > dev , " bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x \n " ,
i , j , iom - > offset , drv - > offset ) ;
2014-06-16 03:36:33 +04:00
/*
* Increase offset according to iomux width .
2014-06-16 03:36:57 +04:00
* 4 bit iomux ' es are spread over two registers .
2014-06-16 03:36:33 +04:00
*/
2017-02-10 13:23:47 +03:00
inc = ( iom - > type & ( IOMUX_WIDTH_4BIT |
2019-10-15 12:17:08 +03:00
IOMUX_WIDTH_3BIT |
IOMUX_WIDTH_2BIT ) ) ? 8 : 4 ;
2014-06-16 03:37:23 +04:00
if ( iom - > type & IOMUX_SOURCE_PMU )
pmu_offs + = inc ;
else
grf_offs + = inc ;
2014-06-16 03:36:33 +04:00
2016-02-01 05:58:21 +03:00
/*
* Increase offset according to drv width .
* 3 bit drive - strenth ' es are spread over two registers .
*/
if ( ( drv - > drv_type = = DRV_TYPE_IO_1V8_3V0_AUTO ) | |
( drv - > drv_type = = DRV_TYPE_IO_3V3_ONLY ) )
inc = 8 ;
else
inc = 4 ;
if ( iom - > type & IOMUX_SOURCE_PMU )
drv_pmu_offs + = inc ;
else
drv_grf_offs + = inc ;
2014-06-16 03:36:33 +04:00
bank_pins + = 8 ;
}
2017-05-26 10:20:20 +03:00
2017-07-21 09:27:14 +03:00
/* calculate the per-bank recalced_mask */
for ( j = 0 ; j < ctrl - > niomux_recalced ; j + + ) {
int pin = 0 ;
if ( ctrl - > iomux_recalced [ j ] . num = = bank - > bank_num ) {
pin = ctrl - > iomux_recalced [ j ] . pin ;
bank - > recalced_mask | = BIT ( pin ) ;
}
}
2017-05-26 10:20:20 +03:00
/* calculate the per-bank route_mask */
for ( j = 0 ; j < ctrl - > niomux_routes ; j + + ) {
int pin = 0 ;
if ( ctrl - > iomux_routes [ j ] . bank_num = = bank - > bank_num ) {
pin = ctrl - > iomux_routes [ j ] . pin ;
bank - > route_mask | = BIT ( pin ) ;
}
}
2013-06-11 00:16:22 +04:00
}
return ctrl ;
}
2014-10-29 14:52:00 +03:00
# define RK3288_GRF_GPIO6C_IOMUX 0x64
# define GPIO6C6_SEL_WRITE_ENABLE BIT(28)
static u32 rk3288_grf_gpio6c_iomux ;
2014-10-29 14:51:59 +03:00
static int __maybe_unused rockchip_pinctrl_suspend ( struct device * dev )
{
struct rockchip_pinctrl * info = dev_get_drvdata ( dev ) ;
2014-10-29 14:52:00 +03:00
int ret = pinctrl_force_sleep ( info - > pctl_dev ) ;
if ( ret )
return ret ;
/*
* RK3288 GPIO6_C6 mux would be modified by Maskrom when resume , so save
* the setting here , and restore it at resume .
*/
if ( info - > ctrl - > type = = RK3288 ) {
ret = regmap_read ( info - > regmap_base , RK3288_GRF_GPIO6C_IOMUX ,
& rk3288_grf_gpio6c_iomux ) ;
if ( ret ) {
pinctrl_force_default ( info - > pctl_dev ) ;
return ret ;
}
}
2014-10-29 14:51:59 +03:00
2014-10-29 14:52:00 +03:00
return 0 ;
2014-10-29 14:51:59 +03:00
}
static int __maybe_unused rockchip_pinctrl_resume ( struct device * dev )
{
struct rockchip_pinctrl * info = dev_get_drvdata ( dev ) ;
2014-10-29 14:52:00 +03:00
int ret = regmap_write ( info - > regmap_base , RK3288_GRF_GPIO6C_IOMUX ,
rk3288_grf_gpio6c_iomux |
GPIO6C6_SEL_WRITE_ENABLE ) ;
if ( ret )
return ret ;
2014-10-29 14:51:59 +03:00
return pinctrl_force_default ( info - > pctl_dev ) ;
}
static SIMPLE_DEV_PM_OPS ( rockchip_pinctrl_dev_pm_ops , rockchip_pinctrl_suspend ,
rockchip_pinctrl_resume ) ;
2013-06-11 00:16:22 +04:00
static int rockchip_pinctrl_probe ( struct platform_device * pdev )
{
struct rockchip_pinctrl * info ;
struct device * dev = & pdev - > dev ;
struct rockchip_pin_ctrl * ctrl ;
2014-05-05 15:59:09 +04:00
struct device_node * np = pdev - > dev . of_node , * node ;
2013-06-11 00:16:22 +04:00
struct resource * res ;
2014-05-05 15:58:20 +04:00
void __iomem * base ;
2013-06-11 00:16:22 +04:00
int ret ;
if ( ! dev - > of_node ) {
dev_err ( dev , " device tree node not found \n " ) ;
return - ENODEV ;
}
2017-12-24 00:07:30 +03:00
info = devm_kzalloc ( dev , sizeof ( * info ) , GFP_KERNEL ) ;
2013-06-11 00:16:22 +04:00
if ( ! info )
return - ENOMEM ;
2014-05-05 15:58:46 +04:00
info - > dev = dev ;
2013-06-11 00:16:22 +04:00
ctrl = rockchip_pinctrl_get_soc_data ( info , pdev ) ;
if ( ! ctrl ) {
dev_err ( dev , " driver data not available \n " ) ;
return - EINVAL ;
}
info - > ctrl = ctrl ;
2014-05-05 15:59:51 +04:00
node = of_parse_phandle ( np , " rockchip,grf " , 0 ) ;
if ( node ) {
info - > regmap_base = syscon_node_to_regmap ( node ) ;
if ( IS_ERR ( info - > regmap_base ) )
return PTR_ERR ( info - > regmap_base ) ;
} else {
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2014-05-05 15:58:20 +04:00
base = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( base ) )
return PTR_ERR ( base ) ;
rockchip_regmap_config . max_register = resource_size ( res ) - 4 ;
2014-05-05 15:59:51 +04:00
rockchip_regmap_config . name = " rockchip,pinctrl " ;
info - > regmap_base = devm_regmap_init_mmio ( & pdev - > dev , base ,
& rockchip_regmap_config ) ;
/* to check for the old dt-bindings */
info - > reg_size = resource_size ( res ) ;
/* Honor the old binding, with pull registers as 2nd resource */
if ( ctrl - > type = = RK3188 & & info - > reg_size < 0x200 ) {
res = platform_get_resource ( pdev , IORESOURCE_MEM , 1 ) ;
base = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( base ) )
return PTR_ERR ( base ) ;
rockchip_regmap_config . max_register =
resource_size ( res ) - 4 ;
rockchip_regmap_config . name = " rockchip,pinctrl-pull " ;
info - > regmap_pull = devm_regmap_init_mmio ( & pdev - > dev ,
base ,
& rockchip_regmap_config ) ;
}
2013-10-16 03:08:42 +04:00
}
2014-05-05 15:59:09 +04:00
/* try to find the optional reference to the pmu syscon */
node = of_parse_phandle ( np , " rockchip,pmu " , 0 ) ;
if ( node ) {
info - > regmap_pmu = syscon_node_to_regmap ( node ) ;
if ( IS_ERR ( info - > regmap_pmu ) )
return PTR_ERR ( info - > regmap_pmu ) ;
}
2013-06-11 00:16:22 +04:00
ret = rockchip_gpiolib_register ( pdev , info ) ;
if ( ret )
return ret ;
ret = rockchip_pinctrl_register ( pdev , info ) ;
if ( ret ) {
rockchip_gpiolib_unregister ( pdev , info ) ;
return ret ;
}
platform_set_drvdata ( pdev , info ) ;
return 0 ;
}
2018-05-14 14:59:51 +03:00
static struct rockchip_pin_bank px30_pin_banks [ ] = {
PIN_BANK_IOMUX_FLAGS ( 0 , 32 , " gpio0 " , IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU
) ,
PIN_BANK_IOMUX_FLAGS ( 1 , 32 , " gpio1 " , IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT
) ,
PIN_BANK_IOMUX_FLAGS ( 2 , 32 , " gpio2 " , IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT
) ,
PIN_BANK_IOMUX_FLAGS ( 3 , 32 , " gpio3 " , IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT
) ,
} ;
static struct rockchip_pin_ctrl px30_pin_ctrl = {
. pin_banks = px30_pin_banks ,
. nr_banks = ARRAY_SIZE ( px30_pin_banks ) ,
. label = " PX30-GPIO " ,
. type = PX30 ,
. grf_mux_offset = 0x0 ,
. pmu_mux_offset = 0x0 ,
. iomux_routes = px30_mux_route_data ,
. niomux_routes = ARRAY_SIZE ( px30_mux_route_data ) ,
. pull_calc_reg = px30_calc_pull_reg_and_bit ,
. drv_calc_reg = px30_calc_drv_reg_and_bit ,
. schmitt_calc_reg = px30_calc_schmitt_reg_and_bit ,
} ;
2017-03-17 20:18:36 +03:00
static struct rockchip_pin_bank rv1108_pin_banks [ ] = {
2016-11-15 13:02:43 +03:00
PIN_BANK_IOMUX_FLAGS ( 0 , 32 , " gpio0 " , IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ) ,
PIN_BANK_IOMUX_FLAGS ( 1 , 32 , " gpio1 " , 0 , 0 , 0 , 0 ) ,
PIN_BANK_IOMUX_FLAGS ( 2 , 32 , " gpio2 " , 0 , 0 , 0 , 0 ) ,
PIN_BANK_IOMUX_FLAGS ( 3 , 32 , " gpio3 " , 0 , 0 , 0 , 0 ) ,
} ;
2017-03-17 20:18:36 +03:00
static struct rockchip_pin_ctrl rv1108_pin_ctrl = {
. pin_banks = rv1108_pin_banks ,
. nr_banks = ARRAY_SIZE ( rv1108_pin_banks ) ,
. label = " RV1108-GPIO " ,
. type = RV1108 ,
2016-11-15 13:02:43 +03:00
. grf_mux_offset = 0x10 ,
. pmu_mux_offset = 0x0 ,
2017-08-23 11:00:07 +03:00
. iomux_recalced = rv1108_mux_recalced_data ,
. niomux_recalced = ARRAY_SIZE ( rv1108_mux_recalced_data ) ,
2017-03-17 20:18:36 +03:00
. pull_calc_reg = rv1108_calc_pull_reg_and_bit ,
. drv_calc_reg = rv1108_calc_drv_reg_and_bit ,
2017-07-31 13:10:22 +03:00
. schmitt_calc_reg = rv1108_calc_schmitt_reg_and_bit ,
2016-11-15 13:02:43 +03:00
} ;
2013-06-11 00:16:22 +04:00
static struct rockchip_pin_bank rk2928_pin_banks [ ] = {
PIN_BANK ( 0 , 32 , " gpio0 " ) ,
PIN_BANK ( 1 , 32 , " gpio1 " ) ,
PIN_BANK ( 2 , 32 , " gpio2 " ) ,
PIN_BANK ( 3 , 32 , " gpio3 " ) ,
} ;
static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
. pin_banks = rk2928_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk2928_pin_banks ) ,
. label = " RK2928-GPIO " ,
2013-10-16 03:07:20 +04:00
. type = RK2928 ,
2014-06-16 03:37:23 +04:00
. grf_mux_offset = 0xa8 ,
2013-10-16 03:07:20 +04:00
. pull_calc_reg = rk2928_calc_pull_reg_and_bit ,
2013-06-11 00:16:22 +04:00
} ;
2015-08-28 08:46:47 +03:00
static struct rockchip_pin_bank rk3036_pin_banks [ ] = {
PIN_BANK ( 0 , 32 , " gpio0 " ) ,
PIN_BANK ( 1 , 32 , " gpio1 " ) ,
PIN_BANK ( 2 , 32 , " gpio2 " ) ,
} ;
static struct rockchip_pin_ctrl rk3036_pin_ctrl = {
. pin_banks = rk3036_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3036_pin_banks ) ,
. label = " RK3036-GPIO " ,
. type = RK2928 ,
. grf_mux_offset = 0xa8 ,
. pull_calc_reg = rk2928_calc_pull_reg_and_bit ,
} ;
2013-06-11 00:16:22 +04:00
static struct rockchip_pin_bank rk3066a_pin_banks [ ] = {
PIN_BANK ( 0 , 32 , " gpio0 " ) ,
PIN_BANK ( 1 , 32 , " gpio1 " ) ,
PIN_BANK ( 2 , 32 , " gpio2 " ) ,
PIN_BANK ( 3 , 32 , " gpio3 " ) ,
PIN_BANK ( 4 , 32 , " gpio4 " ) ,
PIN_BANK ( 6 , 16 , " gpio6 " ) ,
} ;
static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
. pin_banks = rk3066a_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3066a_pin_banks ) ,
. label = " RK3066a-GPIO " ,
2013-10-16 03:07:20 +04:00
. type = RK2928 ,
2014-06-16 03:37:23 +04:00
. grf_mux_offset = 0xa8 ,
2013-10-16 03:07:20 +04:00
. pull_calc_reg = rk2928_calc_pull_reg_and_bit ,
2013-06-11 00:16:22 +04:00
} ;
static struct rockchip_pin_bank rk3066b_pin_banks [ ] = {
PIN_BANK ( 0 , 32 , " gpio0 " ) ,
PIN_BANK ( 1 , 32 , " gpio1 " ) ,
PIN_BANK ( 2 , 32 , " gpio2 " ) ,
PIN_BANK ( 3 , 32 , " gpio3 " ) ,
} ;
static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
. pin_banks = rk3066b_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3066b_pin_banks ) ,
. label = " RK3066b-GPIO " ,
2013-10-16 03:07:20 +04:00
. type = RK3066B ,
2014-06-16 03:37:23 +04:00
. grf_mux_offset = 0x60 ,
2013-06-11 00:16:22 +04:00
} ;
2017-07-21 09:27:15 +03:00
static struct rockchip_pin_bank rk3128_pin_banks [ ] = {
PIN_BANK ( 0 , 32 , " gpio0 " ) ,
PIN_BANK ( 1 , 32 , " gpio1 " ) ,
PIN_BANK ( 2 , 32 , " gpio2 " ) ,
PIN_BANK ( 3 , 32 , " gpio3 " ) ,
} ;
static struct rockchip_pin_ctrl rk3128_pin_ctrl = {
. pin_banks = rk3128_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3128_pin_banks ) ,
. label = " RK3128-GPIO " ,
. type = RK3128 ,
. grf_mux_offset = 0xa8 ,
. iomux_recalced = rk3128_mux_recalced_data ,
. niomux_recalced = ARRAY_SIZE ( rk3128_mux_recalced_data ) ,
. iomux_routes = rk3128_mux_route_data ,
. niomux_routes = ARRAY_SIZE ( rk3128_mux_route_data ) ,
. pull_calc_reg = rk3128_calc_pull_reg_and_bit ,
} ;
2013-06-11 00:16:22 +04:00
static struct rockchip_pin_bank rk3188_pin_banks [ ] = {
2014-06-16 03:36:05 +04:00
PIN_BANK_IOMUX_FLAGS ( 0 , 32 , " gpio0 " , IOMUX_GPIO_ONLY , 0 , 0 , 0 ) ,
2013-06-11 00:16:22 +04:00
PIN_BANK ( 1 , 32 , " gpio1 " ) ,
PIN_BANK ( 2 , 32 , " gpio2 " ) ,
PIN_BANK ( 3 , 32 , " gpio3 " ) ,
} ;
static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
. pin_banks = rk3188_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3188_pin_banks ) ,
. label = " RK3188-GPIO " ,
2013-10-16 03:07:20 +04:00
. type = RK3188 ,
2014-06-16 03:37:23 +04:00
. grf_mux_offset = 0x60 ,
2018-11-12 00:00:47 +03:00
. iomux_routes = rk3188_mux_route_data ,
. niomux_routes = ARRAY_SIZE ( rk3188_mux_route_data ) ,
2013-10-16 03:08:42 +04:00
. pull_calc_reg = rk3188_calc_pull_reg_and_bit ,
2013-06-11 00:16:22 +04:00
} ;
2015-12-09 12:04:06 +03:00
static struct rockchip_pin_bank rk3228_pin_banks [ ] = {
PIN_BANK ( 0 , 32 , " gpio0 " ) ,
PIN_BANK ( 1 , 32 , " gpio1 " ) ,
PIN_BANK ( 2 , 32 , " gpio2 " ) ,
PIN_BANK ( 3 , 32 , " gpio3 " ) ,
} ;
static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
. pin_banks = rk3228_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3228_pin_banks ) ,
. label = " RK3228-GPIO " ,
. type = RK3288 ,
. grf_mux_offset = 0x0 ,
2017-05-26 10:20:21 +03:00
. iomux_routes = rk3228_mux_route_data ,
. niomux_routes = ARRAY_SIZE ( rk3228_mux_route_data ) ,
2015-12-09 12:04:06 +03:00
. pull_calc_reg = rk3228_calc_pull_reg_and_bit ,
. drv_calc_reg = rk3228_calc_drv_reg_and_bit ,
} ;
2014-06-16 03:38:14 +04:00
static struct rockchip_pin_bank rk3288_pin_banks [ ] = {
PIN_BANK_IOMUX_FLAGS ( 0 , 24 , " gpio0 " , IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_UNROUTED
) ,
PIN_BANK_IOMUX_FLAGS ( 1 , 32 , " gpio1 " , IOMUX_UNROUTED ,
IOMUX_UNROUTED ,
IOMUX_UNROUTED ,
0
) ,
PIN_BANK_IOMUX_FLAGS ( 2 , 32 , " gpio2 " , 0 , 0 , 0 , IOMUX_UNROUTED ) ,
PIN_BANK_IOMUX_FLAGS ( 3 , 32 , " gpio3 " , 0 , 0 , 0 , IOMUX_WIDTH_4BIT ) ,
PIN_BANK_IOMUX_FLAGS ( 4 , 32 , " gpio4 " , IOMUX_WIDTH_4BIT ,
IOMUX_WIDTH_4BIT ,
0 ,
0
) ,
PIN_BANK_IOMUX_FLAGS ( 5 , 32 , " gpio5 " , IOMUX_UNROUTED ,
0 ,
0 ,
IOMUX_UNROUTED
) ,
PIN_BANK_IOMUX_FLAGS ( 6 , 32 , " gpio6 " , 0 , 0 , 0 , IOMUX_UNROUTED ) ,
PIN_BANK_IOMUX_FLAGS ( 7 , 32 , " gpio7 " , 0 ,
0 ,
IOMUX_WIDTH_4BIT ,
IOMUX_UNROUTED
) ,
PIN_BANK ( 8 , 16 , " gpio8 " ) ,
} ;
static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
. pin_banks = rk3288_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3288_pin_banks ) ,
. label = " RK3288-GPIO " ,
2014-07-20 03:49:17 +04:00
. type = RK3288 ,
2014-06-16 03:38:14 +04:00
. grf_mux_offset = 0x0 ,
. pmu_mux_offset = 0x84 ,
2017-10-21 11:53:10 +03:00
. iomux_routes = rk3288_mux_route_data ,
. niomux_routes = ARRAY_SIZE ( rk3288_mux_route_data ) ,
2014-06-16 03:38:14 +04:00
. pull_calc_reg = rk3288_calc_pull_reg_and_bit ,
2015-06-13 00:50:11 +03:00
. drv_calc_reg = rk3288_calc_drv_reg_and_bit ,
2014-06-16 03:38:14 +04:00
} ;
2019-10-15 12:17:08 +03:00
static struct rockchip_pin_bank rk3308_pin_banks [ ] = {
PIN_BANK_IOMUX_FLAGS ( 0 , 32 , " gpio0 " , IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ) ,
PIN_BANK_IOMUX_FLAGS ( 1 , 32 , " gpio1 " , IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ) ,
PIN_BANK_IOMUX_FLAGS ( 2 , 32 , " gpio2 " , IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ) ,
PIN_BANK_IOMUX_FLAGS ( 3 , 32 , " gpio3 " , IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ) ,
PIN_BANK_IOMUX_FLAGS ( 4 , 32 , " gpio4 " , IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ,
IOMUX_WIDTH_2BIT ) ,
} ;
static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
. pin_banks = rk3308_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3308_pin_banks ) ,
. label = " RK3308-GPIO " ,
. type = RK3308 ,
. grf_mux_offset = 0x0 ,
. iomux_recalced = rk3308_mux_recalced_data ,
. niomux_recalced = ARRAY_SIZE ( rk3308_mux_recalced_data ) ,
. iomux_routes = rk3308_mux_route_data ,
. niomux_routes = ARRAY_SIZE ( rk3308_mux_route_data ) ,
. pull_calc_reg = rk3308_calc_pull_reg_and_bit ,
. drv_calc_reg = rk3308_calc_drv_reg_and_bit ,
. schmitt_calc_reg = rk3308_calc_schmitt_reg_and_bit ,
} ;
2017-02-10 13:23:49 +03:00
static struct rockchip_pin_bank rk3328_pin_banks [ ] = {
PIN_BANK_IOMUX_FLAGS ( 0 , 32 , " gpio0 " , 0 , 0 , 0 , 0 ) ,
PIN_BANK_IOMUX_FLAGS ( 1 , 32 , " gpio1 " , 0 , 0 , 0 , 0 ) ,
PIN_BANK_IOMUX_FLAGS ( 2 , 32 , " gpio2 " , 0 ,
2017-07-21 09:27:14 +03:00
IOMUX_WIDTH_3BIT ,
IOMUX_WIDTH_3BIT ,
2017-02-10 13:23:49 +03:00
0 ) ,
PIN_BANK_IOMUX_FLAGS ( 3 , 32 , " gpio3 " ,
IOMUX_WIDTH_3BIT ,
2017-07-21 09:27:14 +03:00
IOMUX_WIDTH_3BIT ,
2017-02-10 13:23:49 +03:00
0 ,
0 ) ,
} ;
static struct rockchip_pin_ctrl rk3328_pin_ctrl = {
. pin_banks = rk3328_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3328_pin_banks ) ,
. label = " RK3328-GPIO " ,
. type = RK3288 ,
. grf_mux_offset = 0x0 ,
2017-07-21 09:27:14 +03:00
. iomux_recalced = rk3328_mux_recalced_data ,
. niomux_recalced = ARRAY_SIZE ( rk3328_mux_recalced_data ) ,
2017-05-26 10:20:22 +03:00
. iomux_routes = rk3328_mux_route_data ,
. niomux_routes = ARRAY_SIZE ( rk3328_mux_route_data ) ,
2017-02-10 13:23:49 +03:00
. pull_calc_reg = rk3228_calc_pull_reg_and_bit ,
. drv_calc_reg = rk3228_calc_drv_reg_and_bit ,
2017-03-02 10:11:24 +03:00
. schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit ,
2017-02-10 13:23:49 +03:00
} ;
2015-06-13 00:51:01 +03:00
static struct rockchip_pin_bank rk3368_pin_banks [ ] = {
PIN_BANK_IOMUX_FLAGS ( 0 , 32 , " gpio0 " , IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU
) ,
PIN_BANK ( 1 , 32 , " gpio1 " ) ,
PIN_BANK ( 2 , 32 , " gpio2 " ) ,
PIN_BANK ( 3 , 32 , " gpio3 " ) ,
} ;
static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
. pin_banks = rk3368_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3368_pin_banks ) ,
. label = " RK3368-GPIO " ,
. type = RK3368 ,
. grf_mux_offset = 0x0 ,
. pmu_mux_offset = 0x0 ,
. pull_calc_reg = rk3368_calc_pull_reg_and_bit ,
. drv_calc_reg = rk3368_calc_drv_reg_and_bit ,
} ;
2016-02-01 05:58:21 +03:00
static struct rockchip_pin_bank rk3399_pin_banks [ ] = {
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS ( 0 , 32 , " gpio0 " ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
DRV_TYPE_IO_1V8_ONLY ,
DRV_TYPE_IO_1V8_ONLY ,
DRV_TYPE_IO_DEFAULT ,
DRV_TYPE_IO_DEFAULT ,
2017-09-30 15:13:20 +03:00
0x80 ,
0x88 ,
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
- 1 ,
- 1 ,
PULL_TYPE_IO_1V8_ONLY ,
PULL_TYPE_IO_1V8_ONLY ,
PULL_TYPE_IO_DEFAULT ,
PULL_TYPE_IO_DEFAULT
) ,
2016-02-01 05:58:21 +03:00
PIN_BANK_IOMUX_DRV_FLAGS_OFFSET ( 1 , 32 , " gpio1 " , IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
IOMUX_SOURCE_PMU ,
DRV_TYPE_IO_1V8_OR_3V0 ,
DRV_TYPE_IO_1V8_OR_3V0 ,
DRV_TYPE_IO_1V8_OR_3V0 ,
DRV_TYPE_IO_1V8_OR_3V0 ,
2017-09-30 15:13:20 +03:00
0xa0 ,
0xa8 ,
0xb0 ,
0xb8
2016-02-01 05:58:21 +03:00
) ,
pinctrl: rockchip: fix pull setting error for rk3399
This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).
From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);
Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);
For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-05-11 06:39:28 +03:00
PIN_BANK_DRV_FLAGS_PULL_FLAGS ( 2 , 32 , " gpio2 " , DRV_TYPE_IO_1V8_OR_3V0 ,
DRV_TYPE_IO_1V8_OR_3V0 ,
DRV_TYPE_IO_1V8_ONLY ,
DRV_TYPE_IO_1V8_ONLY ,
PULL_TYPE_IO_DEFAULT ,
PULL_TYPE_IO_DEFAULT ,
PULL_TYPE_IO_1V8_ONLY ,
PULL_TYPE_IO_1V8_ONLY
) ,
2016-02-01 05:58:21 +03:00
PIN_BANK_DRV_FLAGS ( 3 , 32 , " gpio3 " , DRV_TYPE_IO_3V3_ONLY ,
DRV_TYPE_IO_3V3_ONLY ,
DRV_TYPE_IO_3V3_ONLY ,
DRV_TYPE_IO_1V8_OR_3V0
) ,
PIN_BANK_DRV_FLAGS ( 4 , 32 , " gpio4 " , DRV_TYPE_IO_1V8_OR_3V0 ,
DRV_TYPE_IO_1V8_3V0_AUTO ,
DRV_TYPE_IO_1V8_OR_3V0 ,
DRV_TYPE_IO_1V8_OR_3V0
) ,
} ;
static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
. pin_banks = rk3399_pin_banks ,
. nr_banks = ARRAY_SIZE ( rk3399_pin_banks ) ,
. label = " RK3399-GPIO " ,
. type = RK3399 ,
. grf_mux_offset = 0xe000 ,
. pmu_mux_offset = 0x0 ,
. grf_drv_offset = 0xe100 ,
. pmu_drv_offset = 0x80 ,
2017-05-26 10:20:23 +03:00
. iomux_routes = rk3399_mux_route_data ,
. niomux_routes = ARRAY_SIZE ( rk3399_mux_route_data ) ,
2016-02-01 05:58:21 +03:00
. pull_calc_reg = rk3399_calc_pull_reg_and_bit ,
. drv_calc_reg = rk3399_calc_drv_reg_and_bit ,
} ;
2015-06-13 00:51:01 +03:00
2013-06-11 00:16:22 +04:00
static const struct of_device_id rockchip_pinctrl_dt_match [ ] = {
2018-05-14 14:59:51 +03:00
{ . compatible = " rockchip,px30-pinctrl " ,
. data = & px30_pin_ctrl } ,
2017-03-17 20:18:36 +03:00
{ . compatible = " rockchip,rv1108-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rv1108_pin_ctrl } ,
2013-06-11 00:16:22 +04:00
{ . compatible = " rockchip,rk2928-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk2928_pin_ctrl } ,
2015-08-28 08:46:47 +03:00
{ . compatible = " rockchip,rk3036-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk3036_pin_ctrl } ,
2013-06-11 00:16:22 +04:00
{ . compatible = " rockchip,rk3066a-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk3066a_pin_ctrl } ,
2013-06-11 00:16:22 +04:00
{ . compatible = " rockchip,rk3066b-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk3066b_pin_ctrl } ,
2017-07-21 09:27:15 +03:00
{ . compatible = " rockchip,rk3128-pinctrl " ,
. data = ( void * ) & rk3128_pin_ctrl } ,
2013-06-11 00:16:22 +04:00
{ . compatible = " rockchip,rk3188-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk3188_pin_ctrl } ,
2015-12-09 12:04:06 +03:00
{ . compatible = " rockchip,rk3228-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk3228_pin_ctrl } ,
2014-06-16 03:38:14 +04:00
{ . compatible = " rockchip,rk3288-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk3288_pin_ctrl } ,
2019-10-15 12:17:08 +03:00
{ . compatible = " rockchip,rk3308-pinctrl " ,
. data = & rk3308_pin_ctrl } ,
2017-02-10 13:23:49 +03:00
{ . compatible = " rockchip,rk3328-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk3328_pin_ctrl } ,
2015-06-13 00:51:01 +03:00
{ . compatible = " rockchip,rk3368-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk3368_pin_ctrl } ,
2016-02-01 05:58:21 +03:00
{ . compatible = " rockchip,rk3399-pinctrl " ,
2017-04-28 15:50:35 +03:00
. data = & rk3399_pin_ctrl } ,
2013-06-11 00:16:22 +04:00
{ } ,
} ;
static struct platform_driver rockchip_pinctrl_driver = {
. probe = rockchip_pinctrl_probe ,
. driver = {
. name = " rockchip-pinctrl " ,
2014-10-29 14:51:59 +03:00
. pm = & rockchip_pinctrl_dev_pm_ops ,
2013-08-23 10:27:53 +04:00
. of_match_table = rockchip_pinctrl_dt_match ,
2013-06-11 00:16:22 +04:00
} ,
} ;
static int __init rockchip_pinctrl_drv_register ( void )
{
return platform_driver_register ( & rockchip_pinctrl_driver ) ;
}
postcore_initcall ( rockchip_pinctrl_drv_register ) ;