mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge tag 'ASB-2024-07-05_11-5.4' of https://android.googlesource.com/kernel/common into android13-5.4-lahaina
https://source.android.com/docs/security/bulletin/2024-07-01 CVE-2024-26923 * tag 'ASB-2024-07-05_11-5.4' of https://android.googlesource.com/kernel/common: (193 commits) ANDROID: fix kernelci build breaks due to hid/uhid cyclic dependency UPSTREAM: af_unix: Fix garbage collector racing against connect() ANDROID: 16K: Only check basename of linker context UPSTREAM: af_unix: Do not use atomic ops for unix_sk(sk)->inflight. Linux 5.4.276 pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback pinctrl: mediatek: remove set but not used variable 'e' pinctrl: mediatek: Fix some off by one bugs pinctrl: mediatek: Fix fallback behavior for bias_set_combo regulator: core: fix debugfs creation regression net: fix out-of-bounds access in ops_init drm/vmwgfx: Fix invalid reads in fence signaled events dyndbg: fix old BUG_ON in >control parser tipc: fix UAF in error path usb: gadget: f_fs: Fix a race condition when processing setup packets. usb: gadget: composite: fix OS descriptors w_value logic firewire: nosy: ensure user_length is taken into account when fetching packet contents net: qede: use return from qede_parse_flow_attr() for flower net: qede: sanitize 'rc' in qede_add_tc_flower_fltr() ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action() ... Conflicts: net/unix/garbage.c Change-Id: I9d928b110c82362cd82e7e9cc3bb19c664cdd53d
This commit is contained in:
commit
58d1d8f5ba
164 changed files with 1499 additions and 667 deletions
|
|
@ -2054,13 +2054,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
|
|||
|
||||
error = pinctrl_claim_hogs(pctldev);
|
||||
if (error) {
|
||||
dev_err(pctldev->dev, "could not claim hogs: %i\n",
|
||||
error);
|
||||
pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
|
||||
pctldev->desc->npins);
|
||||
mutex_destroy(&pctldev->mutex);
|
||||
kfree(pctldev);
|
||||
|
||||
dev_err(pctldev->dev, "could not claim hogs: %i\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -223,14 +223,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
|
|||
for (state = 0; ; state++) {
|
||||
/* Retrieve the pinctrl-* property */
|
||||
propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
|
||||
if (!propname)
|
||||
return -ENOMEM;
|
||||
if (!propname) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
prop = of_find_property(np, propname, &size);
|
||||
kfree(propname);
|
||||
if (!prop) {
|
||||
if (state == 0) {
|
||||
of_node_put(np);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1070,15 +1070,12 @@ static const struct mtk_pin_soc mt6765_data = {
|
|||
.ngrps = ARRAY_SIZE(mtk_pins_mt6765),
|
||||
.eint_hw = &mt6765_eint_hw,
|
||||
.gpio_m = 0,
|
||||
.ies_present = true,
|
||||
.base_names = mt6765_pinctrl_register_base_names,
|
||||
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
|
||||
.bias_disable_set = mtk_pinconf_bias_disable_set,
|
||||
.bias_disable_get = mtk_pinconf_bias_disable_get,
|
||||
.bias_set = mtk_pinconf_bias_set,
|
||||
.bias_get = mtk_pinconf_bias_get,
|
||||
.drive_set = mtk_pinconf_drive_set_rev1,
|
||||
.drive_get = mtk_pinconf_drive_get_rev1,
|
||||
.bias_set_combo = mtk_pinconf_bias_set_combo,
|
||||
.bias_get_combo = mtk_pinconf_bias_get_combo,
|
||||
.drive_set = mtk_pinconf_drive_set_raw,
|
||||
.drive_get = mtk_pinconf_drive_get_raw,
|
||||
.adv_pull_get = mtk_pinconf_adv_pull_get,
|
||||
.adv_pull_set = mtk_pinconf_adv_pull_set,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -554,13 +554,10 @@ static const struct mtk_pin_soc mt8183_data = {
|
|||
.ngrps = ARRAY_SIZE(mtk_pins_mt8183),
|
||||
.eint_hw = &mt8183_eint_hw,
|
||||
.gpio_m = 0,
|
||||
.ies_present = true,
|
||||
.base_names = mt8183_pinctrl_register_base_names,
|
||||
.nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
|
||||
.bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
|
||||
.bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
|
||||
.bias_set = mtk_pinconf_bias_set_rev1,
|
||||
.bias_get = mtk_pinconf_bias_get_rev1,
|
||||
.bias_set_combo = mtk_pinconf_bias_set_combo,
|
||||
.bias_get_combo = mtk_pinconf_bias_get_combo,
|
||||
.drive_set = mtk_pinconf_drive_set_rev1,
|
||||
.drive_get = mtk_pinconf_drive_get_rev1,
|
||||
.adv_pull_get = mtk_pinconf_adv_pull_get,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <dt-bindings/pinctrl/mt65xx.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
|
@ -66,34 +67,44 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
|
|||
const struct mtk_pin_desc *desc,
|
||||
int field, struct mtk_pin_field *pfd)
|
||||
{
|
||||
const struct mtk_pin_field_calc *c, *e;
|
||||
const struct mtk_pin_field_calc *c;
|
||||
const struct mtk_pin_reg_calc *rc;
|
||||
int start = 0, end, check;
|
||||
bool found = false;
|
||||
u32 bits;
|
||||
|
||||
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
|
||||
rc = &hw->soc->reg_cal[field];
|
||||
} else {
|
||||
dev_dbg(hw->dev,
|
||||
"Not support field %d for pin %d (%s)\n",
|
||||
field, desc->number, desc->name);
|
||||
"Not support field %d for this soc\n", field);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
c = rc->range;
|
||||
e = c + rc->nranges;
|
||||
end = rc->nranges - 1;
|
||||
|
||||
while (c < e) {
|
||||
if (desc->number >= c->s_pin && desc->number <= c->e_pin)
|
||||
while (start <= end) {
|
||||
check = (start + end) >> 1;
|
||||
if (desc->number >= rc->range[check].s_pin
|
||||
&& desc->number <= rc->range[check].e_pin) {
|
||||
found = true;
|
||||
break;
|
||||
c++;
|
||||
} else if (start == end)
|
||||
break;
|
||||
else if (desc->number < rc->range[check].s_pin)
|
||||
end = check - 1;
|
||||
else
|
||||
start = check + 1;
|
||||
}
|
||||
|
||||
if (c >= e) {
|
||||
if (!found) {
|
||||
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
|
||||
field, desc->number, desc->name);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
c = rc->range + check;
|
||||
|
||||
if (c->i_base > hw->nbase - 1) {
|
||||
dev_err(hw->dev,
|
||||
"Invalid base for field %d for pin = %d (%s)\n",
|
||||
|
|
@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (value < 0 || value > pf.mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pf.next)
|
||||
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
|
||||
(value & pf.mask) << pf.bitpos);
|
||||
|
|
@ -506,6 +520,226 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Combo for the following pull register type:
|
||||
* 1. PU + PD
|
||||
* 2. PULLSEL + PULLEN
|
||||
* 3. PUPD + R0 + R1
|
||||
*/
|
||||
static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 pullup, u32 arg)
|
||||
{
|
||||
int err, pu, pd;
|
||||
|
||||
if (arg == MTK_DISABLE) {
|
||||
pu = 0;
|
||||
pd = 0;
|
||||
} else if ((arg == MTK_ENABLE) && pullup) {
|
||||
pu = 1;
|
||||
pd = 0;
|
||||
} else if ((arg == MTK_ENABLE) && !pullup) {
|
||||
pu = 0;
|
||||
pd = 1;
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 pullup, u32 arg)
|
||||
{
|
||||
int err, enable;
|
||||
|
||||
if (arg == MTK_DISABLE)
|
||||
enable = 0;
|
||||
else if (arg == MTK_ENABLE)
|
||||
enable = 1;
|
||||
else {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 pullup, u32 arg)
|
||||
{
|
||||
int err, r0, r1;
|
||||
|
||||
if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
|
||||
pullup = 0;
|
||||
r0 = 0;
|
||||
r1 = 0;
|
||||
} else if (arg == MTK_PUPD_SET_R1R0_01) {
|
||||
r0 = 1;
|
||||
r1 = 0;
|
||||
} else if (arg == MTK_PUPD_SET_R1R0_10) {
|
||||
r0 = 0;
|
||||
r1 = 1;
|
||||
} else if (arg == MTK_PUPD_SET_R1R0_11) {
|
||||
r0 = 1;
|
||||
r1 = 1;
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 *pullup, u32 *enable)
|
||||
{
|
||||
int err, pu, pd;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (pu == 0 && pd == 0) {
|
||||
*pullup = 0;
|
||||
*enable = MTK_DISABLE;
|
||||
} else if (pu == 1 && pd == 0) {
|
||||
*pullup = 1;
|
||||
*enable = MTK_ENABLE;
|
||||
} else if (pu == 0 && pd == 1) {
|
||||
*pullup = 0;
|
||||
*enable = MTK_ENABLE;
|
||||
} else
|
||||
err = -EINVAL;
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 *pullup, u32 *enable)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 *pullup, u32 *enable)
|
||||
{
|
||||
int err, r0, r1;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
|
||||
if (err)
|
||||
goto out;
|
||||
/* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
|
||||
*pullup = !(*pullup);
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if ((r1 == 0) && (r0 == 0))
|
||||
*enable = MTK_PUPD_SET_R1R0_00;
|
||||
else if ((r1 == 0) && (r0 == 1))
|
||||
*enable = MTK_PUPD_SET_R1R0_01;
|
||||
else if ((r1 == 1) && (r0 == 0))
|
||||
*enable = MTK_PUPD_SET_R1R0_10;
|
||||
else if ((r1 == 1) && (r0 == 1))
|
||||
*enable = MTK_PUPD_SET_R1R0_11;
|
||||
else
|
||||
err = -EINVAL;
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 pullup, u32 arg)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
|
||||
if (!err)
|
||||
goto out;
|
||||
|
||||
err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
|
||||
if (!err)
|
||||
goto out;
|
||||
|
||||
err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 *pullup, u32 *enable)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
|
||||
if (!err)
|
||||
goto out;
|
||||
|
||||
err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
|
||||
if (!err)
|
||||
goto out;
|
||||
|
||||
err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Revision 0 */
|
||||
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, u32 arg)
|
||||
|
|
@ -597,6 +831,18 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, u32 arg)
|
||||
{
|
||||
return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
|
||||
}
|
||||
|
||||
int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, int *val)
|
||||
{
|
||||
return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
|
||||
}
|
||||
|
||||
int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, bool pullup,
|
||||
u32 arg)
|
||||
|
|
@ -630,7 +876,9 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
|
|||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
err = mtk_pinconf_bias_set_rev1(hw, desc, pullup);
|
||||
if (err)
|
||||
err = mtk_pinconf_bias_set(hw, desc, pullup);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -216,6 +216,11 @@ struct mtk_pin_soc {
|
|||
int (*bias_get)(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, bool pullup, int *res);
|
||||
|
||||
int (*bias_set_combo)(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
|
||||
int (*bias_get_combo)(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
|
||||
|
||||
int (*drive_set)(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, u32 arg);
|
||||
int (*drive_get)(struct mtk_pinctrl *hw,
|
||||
|
|
@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
|
|||
int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, bool pullup,
|
||||
int *res);
|
||||
int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 pullup, u32 enable);
|
||||
int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc,
|
||||
u32 *pullup, u32 *enable);
|
||||
|
||||
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, u32 arg);
|
||||
|
|
@ -288,6 +299,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
|
|||
int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, int *val);
|
||||
|
||||
int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, u32 arg);
|
||||
int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, int *val);
|
||||
|
||||
int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
|
||||
const struct mtk_pin_desc *desc, bool pullup,
|
||||
u32 arg);
|
||||
|
|
|
|||
|
|
@ -78,123 +78,101 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
|
|||
{
|
||||
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
|
||||
u32 param = pinconf_to_config_param(*config);
|
||||
int val, val2, err, reg, ret = 1;
|
||||
int pullup, reg, err = -ENOTSUPP, ret = 1;
|
||||
const struct mtk_pin_desc *desc;
|
||||
|
||||
if (pin >= hw->soc->npins)
|
||||
return -EINVAL;
|
||||
|
||||
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
if (hw->soc->bias_disable_get) {
|
||||
err = hw->soc->bias_disable_get(hw, desc, &ret);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
if (hw->soc->bias_get) {
|
||||
err = hw->soc->bias_get(hw, desc, 1, &ret);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
if (hw->soc->bias_get) {
|
||||
err = hw->soc->bias_get(hw, desc, 0, &ret);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
if (!hw->soc->bias_get_combo)
|
||||
break;
|
||||
err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
|
||||
if (err)
|
||||
break;
|
||||
if (ret == MTK_PUPD_SET_R1R0_00)
|
||||
ret = MTK_DISABLE;
|
||||
if (param == PIN_CONFIG_BIAS_DISABLE) {
|
||||
if (ret != MTK_DISABLE)
|
||||
err = -EINVAL;
|
||||
} else if (param == PIN_CONFIG_BIAS_PULL_UP) {
|
||||
if (!pullup || ret == MTK_DISABLE)
|
||||
err = -EINVAL;
|
||||
} else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
|
||||
if (pullup || ret == MTK_DISABLE)
|
||||
err = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case PIN_CONFIG_SLEW_RATE:
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
case PIN_CONFIG_OUTPUT_ENABLE:
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret);
|
||||
if (!ret)
|
||||
err = -EINVAL;
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT:
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
|
||||
/* HW takes input mode as zero; output mode as non-zero */
|
||||
if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
|
||||
(!val && param == PIN_CONFIG_OUTPUT_ENABLE))
|
||||
return -EINVAL;
|
||||
if (!ret) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (val || !val2)
|
||||
return -EINVAL;
|
||||
break;
|
||||
/* return error when in output mode
|
||||
* because schmitt trigger only work in input mode
|
||||
*/
|
||||
if (ret) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
|
||||
if (!ret)
|
||||
err = -EINVAL;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
if (hw->soc->drive_get) {
|
||||
err = hw->soc->drive_get(hw, desc, &ret);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
err = -ENOTSUPP;
|
||||
}
|
||||
if (!hw->soc->drive_get)
|
||||
break;
|
||||
err = hw->soc->drive_get(hw, desc, &ret);
|
||||
break;
|
||||
case MTK_PIN_CONFIG_TDSEL:
|
||||
case MTK_PIN_CONFIG_RDSEL:
|
||||
reg = (param == MTK_PIN_CONFIG_TDSEL) ?
|
||||
PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, reg, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ret = val;
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, reg, &ret);
|
||||
break;
|
||||
case MTK_PIN_CONFIG_PU_ADV:
|
||||
case MTK_PIN_CONFIG_PD_ADV:
|
||||
if (hw->soc->adv_pull_get) {
|
||||
bool pullup;
|
||||
|
||||
pullup = param == MTK_PIN_CONFIG_PU_ADV;
|
||||
err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
if (!hw->soc->adv_pull_get)
|
||||
break;
|
||||
pullup = param == MTK_PIN_CONFIG_PU_ADV;
|
||||
err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
|
||||
break;
|
||||
case MTK_PIN_CONFIG_DRV_ADV:
|
||||
if (hw->soc->adv_drive_get) {
|
||||
err = hw->soc->adv_drive_get(hw, desc, &ret);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
if (!hw->soc->adv_drive_get)
|
||||
break;
|
||||
err = hw->soc->adv_drive_get(hw, desc, &ret);
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
*config = pinconf_to_config_packed(param, ret);
|
||||
if (!err)
|
||||
*config = pinconf_to_config_packed(param, ret);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
|
|
@ -202,140 +180,84 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
|||
{
|
||||
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct mtk_pin_desc *desc;
|
||||
int err = 0;
|
||||
int err = -ENOTSUPP;
|
||||
u32 reg;
|
||||
|
||||
if (pin >= hw->soc->npins)
|
||||
return -EINVAL;
|
||||
|
||||
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
|
||||
|
||||
switch ((u32)param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
if (hw->soc->bias_disable_set) {
|
||||
err = hw->soc->bias_disable_set(hw, desc);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
if (!hw->soc->bias_set_combo)
|
||||
break;
|
||||
err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
if (hw->soc->bias_set) {
|
||||
err = hw->soc->bias_set(hw, desc, 1);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
if (!hw->soc->bias_set_combo)
|
||||
break;
|
||||
err = hw->soc->bias_set_combo(hw, desc, 1, arg);
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
if (hw->soc->bias_set) {
|
||||
err = hw->soc->bias_set(hw, desc, 0);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT_ENABLE:
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
|
||||
MTK_DISABLE);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
|
||||
MTK_OUTPUT);
|
||||
if (err)
|
||||
goto err;
|
||||
if (!hw->soc->bias_set_combo)
|
||||
break;
|
||||
err = hw->soc->bias_set_combo(hw, desc, 0, arg);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
if (hw->soc->ies_present) {
|
||||
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,
|
||||
MTK_ENABLE);
|
||||
}
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
|
||||
MTK_INPUT);
|
||||
if (err)
|
||||
goto err;
|
||||
/* regard all non-zero value as enable */
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
|
||||
break;
|
||||
case PIN_CONFIG_SLEW_RATE:
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,
|
||||
arg);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
/* regard all non-zero value as enable */
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg);
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT:
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
|
||||
MTK_OUTPUT);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
|
||||
arg);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT:
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
/* arg = 1: Input mode & SMT enable ;
|
||||
* arg = 0: Output mode & SMT disable
|
||||
*/
|
||||
arg = arg ? 2 : 1;
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
|
||||
arg & 1);
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
|
||||
!!(arg & 2));
|
||||
if (err)
|
||||
goto err;
|
||||
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
if (hw->soc->drive_set) {
|
||||
err = hw->soc->drive_set(hw, desc, arg);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
if (!hw->soc->drive_set)
|
||||
break;
|
||||
err = hw->soc->drive_set(hw, desc, arg);
|
||||
break;
|
||||
case MTK_PIN_CONFIG_TDSEL:
|
||||
case MTK_PIN_CONFIG_RDSEL:
|
||||
reg = (param == MTK_PIN_CONFIG_TDSEL) ?
|
||||
PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
|
||||
|
||||
err = mtk_hw_set_value(hw, desc, reg, arg);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
case MTK_PIN_CONFIG_PU_ADV:
|
||||
case MTK_PIN_CONFIG_PD_ADV:
|
||||
if (hw->soc->adv_pull_set) {
|
||||
bool pullup;
|
||||
|
||||
pullup = param == MTK_PIN_CONFIG_PU_ADV;
|
||||
err = hw->soc->adv_pull_set(hw, desc, pullup,
|
||||
arg);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
if (!hw->soc->adv_pull_set)
|
||||
break;
|
||||
err = hw->soc->adv_pull_set(hw, desc,
|
||||
(param == MTK_PIN_CONFIG_PU_ADV),
|
||||
arg);
|
||||
break;
|
||||
case MTK_PIN_CONFIG_DRV_ADV:
|
||||
if (hw->soc->adv_drive_set) {
|
||||
err = hw->soc->adv_drive_set(hw, desc, arg);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
if (!hw->soc->adv_drive_set)
|
||||
break;
|
||||
err = hw->soc->adv_drive_set(hw, desc, arg);
|
||||
break;
|
||||
default:
|
||||
err = -ENOTSUPP;
|
||||
}
|
||||
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -690,6 +612,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
|
|||
const struct mtk_pin_desc *desc;
|
||||
int value, err;
|
||||
|
||||
if (gpio >= hw->soc->npins)
|
||||
return -EINVAL;
|
||||
|
||||
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
|
||||
|
|
@ -705,6 +630,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
|
|||
const struct mtk_pin_desc *desc;
|
||||
int value, err;
|
||||
|
||||
if (gpio >= hw->soc->npins)
|
||||
return -EINVAL;
|
||||
|
||||
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
|
||||
|
||||
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
|
||||
|
|
@ -719,6 +647,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
|
|||
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
|
||||
const struct mtk_pin_desc *desc;
|
||||
|
||||
if (gpio >= hw->soc->npins)
|
||||
return;
|
||||
|
||||
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
|
||||
|
||||
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
|
||||
|
|
@ -726,12 +657,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
|
|||
|
||||
static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
|
||||
{
|
||||
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
|
||||
|
||||
if (gpio >= hw->soc->npins)
|
||||
return -EINVAL;
|
||||
|
||||
return pinctrl_gpio_direction_input(chip->base + gpio);
|
||||
}
|
||||
|
||||
static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
|
||||
int value)
|
||||
{
|
||||
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
|
||||
|
||||
if (gpio >= hw->soc->npins)
|
||||
return -EINVAL;
|
||||
|
||||
mtk_gpio_set(chip, gpio, value);
|
||||
|
||||
return pinctrl_gpio_direction_output(chip->base + gpio);
|
||||
|
|
|
|||
Loading…
Reference in a new issue