Commit 325a86b6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'mfd-for-linus-3.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6

Pull MFD fixes from Samuel Ortiz:
 "This is the first pull request for MFD fixes for 3.8

  We have some build failure fixes (twl4030, vexpress, abx500 and
  tps65910), some actual runtime oops and lockup fixes (rtsx, da9052),
  and some more hypothetical NULL pointers dereferences fixes for
  pcf50633 and max776xx.

  Then we also have additional rtsx fixes for a correct switch output
  voltage and clock divider correctness for rtl8411 (rtsx driver), and
  irqdomain fix for db8550-prcmu, and some more cosmetic fixes for
  arizona and wm5102."

* tag 'mfd-for-linus-3.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6:
  mfd: rtsx: Fix oops when rtsx_pci_sdmmc is not probed
  mfd: wm5102: Fix definition of WM5102_MAX_REGISTER
  mfd: twl4030: Don't warn about uninitialized return code
  mfd: da9052/53 lockup fix
  mfd: rtsx: Add clock divider hook
  mmc: rtsx: Call MFD hook to switch output voltage
  mfd: rtsx: Add output voltage switch hook
  mfd: Fix compile errors and warnings when !CONFIG_AB8500_BM
  mfd: vexpress: Export global functions to fix build error
  mfd: arizona: Check errors from regcache_sync()
  mfd: tc3589x: Use simple irqdomain
  mfd: pcf50633: Init pcf->dev before using it
  mfd: max77693: Init max77693->dev before using it
  mfd: max77686: Init max77686->dev before using it
  mfd: db8500-prcmu: Fix irqdomain usage
  mfd: tps65910: Select REGMAP_IRQ in Kconfig to fix build error
  mfd: arizona: Disable control interface reporting for WM5102 and WM5110
parents 22f83798 2d1484f5
......@@ -237,6 +237,7 @@ config MFD_TPS65910
depends on I2C=y && GPIOLIB
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
select IRQ_DOMAIN
help
if you say yes here you get support for the TPS65910 series of
......
......@@ -19,6 +19,7 @@
#include <linux/mfd/core.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/abx500/ab8500-bm.h>
#include <linux/mfd/dbx500-prcmu.h>
#include <linux/regulator/ab8500.h>
#include <linux/of.h>
......
......@@ -239,7 +239,12 @@ static int arizona_runtime_resume(struct device *dev)
return ret;
}
regcache_sync(arizona->regmap);
ret = regcache_sync(arizona->regmap);
if (ret != 0) {
dev_err(arizona->dev, "Failed to restore register cache\n");
regulator_disable(arizona->dcvdd);
return ret;
}
return 0;
}
......
......@@ -176,14 +176,7 @@ int arizona_irq_init(struct arizona *arizona)
aod = &wm5102_aod;
irq = &wm5102_irq;
switch (arizona->rev) {
case 0:
case 1:
ctrlif_error = false;
break;
default:
break;
}
ctrlif_error = false;
break;
#endif
#ifdef CONFIG_MFD_WM5110
......@@ -191,14 +184,7 @@ int arizona_irq_init(struct arizona *arizona)
aod = &wm5110_aod;
irq = &wm5110_irq;
switch (arizona->rev) {
case 0:
case 1:
ctrlif_error = false;
break;
default:
break;
}
ctrlif_error = false;
break;
#endif
default:
......
......@@ -27,6 +27,66 @@
#include <linux/of_device.h>
#endif
/* I2C safe register check */
static inline bool i2c_safe_reg(unsigned char reg)
{
switch (reg) {
case DA9052_STATUS_A_REG:
case DA9052_STATUS_B_REG:
case DA9052_STATUS_C_REG:
case DA9052_STATUS_D_REG:
case DA9052_ADC_RES_L_REG:
case DA9052_ADC_RES_H_REG:
case DA9052_VDD_RES_REG:
case DA9052_ICHG_AV_REG:
case DA9052_TBAT_RES_REG:
case DA9052_ADCIN4_RES_REG:
case DA9052_ADCIN5_RES_REG:
case DA9052_ADCIN6_RES_REG:
case DA9052_TJUNC_RES_REG:
case DA9052_TSI_X_MSB_REG:
case DA9052_TSI_Y_MSB_REG:
case DA9052_TSI_LSB_REG:
case DA9052_TSI_Z_MSB_REG:
return true;
default:
return false;
}
}
/*
* There is an issue with DA9052 and DA9053_AA/BA/BB PMIC where the PMIC
* gets lockup up or fails to respond following a system reset.
* This fix is to follow any read or write with a dummy read to a safe
* register.
*/
int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
{
int val;
switch (da9052->chip_id) {
case DA9052:
case DA9053_AA:
case DA9053_BA:
case DA9053_BB:
/* A dummy read to a safe register address. */
if (!i2c_safe_reg(reg))
return regmap_read(da9052->regmap,
DA9052_PARK_REGISTER,
&val);
break;
default:
/*
* For other chips parking of I2C register
* to a safe place is not required.
*/
break;
}
return 0;
}
EXPORT_SYMBOL(da9052_i2c_fix);
static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
{
int reg_val, ret;
......@@ -83,6 +143,7 @@ static int da9052_i2c_probe(struct i2c_client *client,
da9052->dev = &client->dev;
da9052->chip_irq = client->irq;
da9052->fix_io = da9052_i2c_fix;
i2c_set_clientdata(client, da9052);
......
......@@ -2524,7 +2524,7 @@ static bool read_mailbox_0(void)
for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) {
if (ev & prcmu_irq_bit[n])
generic_handle_irq(IRQ_PRCMU_BASE + n);
generic_handle_irq(irq_find_mapping(db8500_irq_domain, n));
}
r = true;
break;
......@@ -2737,13 +2737,14 @@ static int db8500_irq_map(struct irq_domain *d, unsigned int virq,
}
static struct irq_domain_ops db8500_irq_ops = {
.map = db8500_irq_map,
.xlate = irq_domain_xlate_twocell,
.map = db8500_irq_map,
.xlate = irq_domain_xlate_twocell,
};
static int db8500_irq_init(struct device_node *np)
{
int irq_base = -1;
int irq_base = 0;
int i;
/* In the device tree case, just take some IRQs */
if (!np)
......@@ -2758,6 +2759,10 @@ static int db8500_irq_init(struct device_node *np)
return -ENOSYS;
}
/* All wakeups will be used, so create mappings for all */
for (i = 0; i < NUM_PRCMU_WAKEUPS; i++)
irq_create_mapping(db8500_irq_domain, i);
return 0;
}
......
......@@ -93,15 +93,6 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
if (max77686 == NULL)
return -ENOMEM;
max77686->regmap = regmap_init_i2c(i2c, &max77686_regmap_config);
if (IS_ERR(max77686->regmap)) {
ret = PTR_ERR(max77686->regmap);
dev_err(max77686->dev, "Failed to allocate register map: %d\n",
ret);
kfree(max77686);
return ret;
}
i2c_set_clientdata(i2c, max77686);
max77686->dev = &i2c->dev;
max77686->i2c = i2c;
......@@ -111,6 +102,15 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
max77686->irq_gpio = pdata->irq_gpio;
max77686->irq = i2c->irq;
max77686->regmap = regmap_init_i2c(i2c, &max77686_regmap_config);
if (IS_ERR(max77686->regmap)) {
ret = PTR_ERR(max77686->regmap);
dev_err(max77686->dev, "Failed to allocate register map: %d\n",
ret);
kfree(max77686);
return ret;
}
if (regmap_read(max77686->regmap,
MAX77686_REG_DEVICE_ID, &data) < 0) {
dev_err(max77686->dev,
......
......@@ -114,35 +114,37 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
u8 reg_data;
int ret = 0;
if (!pdata) {
dev_err(&i2c->dev, "No platform data found.\n");
return -EINVAL;
}
max77693 = devm_kzalloc(&i2c->dev,
sizeof(struct max77693_dev), GFP_KERNEL);
if (max77693 == NULL)
return -ENOMEM;
max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config);
if (IS_ERR(max77693->regmap)) {
ret = PTR_ERR(max77693->regmap);
dev_err(max77693->dev,"failed to allocate register map: %d\n",
ret);
goto err_regmap;
}
i2c_set_clientdata(i2c, max77693);
max77693->dev = &i2c->dev;
max77693->i2c = i2c;
max77693->irq = i2c->irq;
max77693->type = id->driver_data;
if (!pdata)
goto err_regmap;
max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config);
if (IS_ERR(max77693->regmap)) {
ret = PTR_ERR(max77693->regmap);
dev_err(max77693->dev, "failed to allocate register map: %d\n",
ret);
return ret;
}
max77693->wakeup = pdata->wakeup;
if (max77693_read_reg(max77693->regmap,
MAX77693_PMIC_REG_PMIC_ID2, &reg_data) < 0) {
ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
&reg_data);
if (ret < 0) {
dev_err(max77693->dev, "device not found on this channel\n");
ret = -ENODEV;
goto err_regmap;
return ret;
} else
dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
......@@ -163,7 +165,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
ret = PTR_ERR(max77693->regmap_muic);
dev_err(max77693->dev,
"failed to allocate register map: %d\n", ret);
goto err_regmap;
goto err_regmap_muic;
}
ret = max77693_irq_init(max77693);
......@@ -184,9 +186,9 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
err_mfd:
max77693_irq_exit(max77693);
err_irq:
err_regmap_muic:
i2c_unregister_device(max77693->muic);
i2c_unregister_device(max77693->haptic);
err_regmap:
return ret;
}
......
......@@ -208,6 +208,8 @@ static int pcf50633_probe(struct i2c_client *client,
if (!pcf)
return -ENOMEM;
i2c_set_clientdata(client, pcf);
pcf->dev = &client->dev;
pcf->pdata = pdata;
mutex_init(&pcf->lock);
......@@ -219,9 +221,6 @@ static int pcf50633_probe(struct i2c_client *client,
return ret;
}
i2c_set_clientdata(client, pcf);
pcf->dev = &client->dev;
version = pcf50633_reg_read(pcf, 0);
variant = pcf50633_reg_read(pcf, 1);
if (version < 0 || variant < 0) {
......
......@@ -112,6 +112,21 @@ static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card)
BPP_LDO_POWB, BPP_LDO_SUSPEND);
}
static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
u8 mask, val;
mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK;
if (voltage == OUTPUT_3V3)
val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3;
else if (voltage == OUTPUT_1V8)
val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8;
else
return -EINVAL;
return rtsx_pci_write_register(pcr, LDO_CTL, mask, val);
}
static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
{
unsigned int card_exist;
......@@ -163,6 +178,18 @@ static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
return card_exist;
}
static int rtl8411_conv_clk_and_div_n(int input, int dir)
{
int output;
if (dir == CLK_TO_DIV_N)
output = input * 4 / 5 - 2;
else
output = (input + 2) * 5 / 4;
return output;
}
static const struct pcr_ops rtl8411_pcr_ops = {
.extra_init_hw = rtl8411_extra_init_hw,
.optimize_phy = NULL,
......@@ -172,7 +199,9 @@ static const struct pcr_ops rtl8411_pcr_ops = {
.disable_auto_blink = rtl8411_disable_auto_blink,
.card_power_on = rtl8411_card_power_on,
.card_power_off = rtl8411_card_power_off,
.switch_output_voltage = rtl8411_switch_output_voltage,
.cd_deglitch = rtl8411_cd_deglitch,
.conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
};
/* SD Pull Control Enable:
......
......@@ -144,6 +144,25 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
int err;
if (voltage == OUTPUT_3V3) {
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
if (err < 0)
return err;
} else if (voltage == OUTPUT_1V8) {
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
if (err < 0)
return err;
} else {
return -EINVAL;
}
return 0;
}
static const struct pcr_ops rts5209_pcr_ops = {
.extra_init_hw = rts5209_extra_init_hw,
.optimize_phy = rts5209_optimize_phy,
......@@ -153,7 +172,9 @@ static const struct pcr_ops rts5209_pcr_ops = {
.disable_auto_blink = rts5209_disable_auto_blink,
.card_power_on = rts5209_card_power_on,
.card_power_off = rts5209_card_power_off,
.switch_output_voltage = rts5209_switch_output_voltage,
.cd_deglitch = NULL,
.conv_clk_and_div_n = NULL,
};
/* SD Pull Control Enable:
......
......@@ -114,6 +114,25 @@ static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card)
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
int err;
if (voltage == OUTPUT_3V3) {
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
if (err < 0)
return err;
} else if (voltage == OUTPUT_1V8) {
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
if (err < 0)
return err;
} else {
return -EINVAL;
}
return 0;
}
static const struct pcr_ops rts5229_pcr_ops = {
.extra_init_hw = rts5229_extra_init_hw,
.optimize_phy = rts5229_optimize_phy,
......@@ -123,7 +142,9 @@ static const struct pcr_ops rts5229_pcr_ops = {
.disable_auto_blink = rts5229_disable_auto_blink,
.card_power_on = rts5229_card_power_on,
.card_power_off = rts5229_card_power_off,
.switch_output_voltage = rts5229_switch_output_voltage,
.cd_deglitch = NULL,
.conv_clk_and_div_n = NULL,
};
/* SD Pull Control Enable:
......
......@@ -630,7 +630,10 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
if (clk == pcr->cur_clock)
return 0;
N = (u8)(clk - 2);
if (pcr->ops->conv_clk_and_div_n)
N = (u8)pcr->ops->conv_clk_and_div_n(clk, CLK_TO_DIV_N);
else
N = (u8)(clk - 2);
if ((clk <= 2) || (N > max_N))
return -EINVAL;
......@@ -641,7 +644,14 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
/* Make sure that the SSC clock div_n is equal or greater than min_N */
div = CLK_DIV_1;
while ((N < min_N) && (div < max_div)) {
N = (N + 2) * 2 - 2;
if (pcr->ops->conv_clk_and_div_n) {
int dbl_clk = pcr->ops->conv_clk_and_div_n(N,
DIV_N_TO_CLK) * 2;
N = (u8)pcr->ops->conv_clk_and_div_n(dbl_clk,
CLK_TO_DIV_N);
} else {
N = (N + 2) * 2 - 2;
}
div++;
}
dev_dbg(&(pcr->pci->dev), "N = %d, div = %d\n", N, div);
......@@ -703,6 +713,15 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card)
}
EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off);
int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
if (pcr->ops->switch_output_voltage)
return pcr->ops->switch_output_voltage(pcr, voltage);
return 0;
}
EXPORT_SYMBOL_GPL(rtsx_pci_switch_output_voltage);
unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr)
{
unsigned int val;
......@@ -767,10 +786,10 @@ static void rtsx_pci_card_detect(struct work_struct *work)
spin_unlock_irqrestore(&pcr->lock, flags);
if (card_detect & SD_EXIST)
if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event)
pcr->slots[RTSX_SD_CARD].card_event(
pcr->slots[RTSX_SD_CARD].p_dev);
if (card_detect & MS_EXIST)
if ((card_detect & MS_EXIST) && pcr->slots[RTSX_MS_CARD].card_event)
pcr->slots[RTSX_MS_CARD].card_event(
pcr->slots[RTSX_MS_CARD].p_dev);
}
......
......@@ -219,25 +219,18 @@ static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq)
}
static struct irq_domain_ops tc3589x_irq_ops = {
.map = tc3589x_irq_map,
.map = tc3589x_irq_map,
.unmap = tc3589x_irq_unmap,
.xlate = irq_domain_xlate_twocell,
.xlate = irq_domain_xlate_twocell,
};
static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np)
{
int base = tc3589x->irq_base;
if (base) {
tc3589x->domain = irq_domain_add_legacy(
NULL, TC3589x_NR_INTERNAL_IRQS, base,
0, &tc3589x_irq_ops, tc3589x);
}
else {
tc3589x->domain = irq_domain_add_linear(
np, TC3589x_NR_INTERNAL_IRQS,
&tc3589x_irq_ops, tc3589x);
}
tc3589x->domain = irq_domain_add_simple(
np, TC3589x_NR_INTERNAL_IRQS, base,
&tc3589x_irq_ops, tc3589x);
if (!tc3589x->domain) {
dev_err(tc3589x->dev, "Failed to create irqdomain\n");
......
......@@ -159,7 +159,7 @@ static int twl4030_write_script_ins(u8 address, u16 pmb_message,
static int twl4030_write_script(u8 address, struct twl4030_ins *script,
int len)
{
int err;
int err = -EINVAL;
for (; len; len--, address++, script++) {
if (len == 1) {
......
......@@ -67,6 +67,7 @@ struct vexpress_config_bridge *vexpress_config_bridge_register(
return bridge;
}
EXPORT_SYMBOL(vexpress_config_bridge_register);
void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)
{
......@@ -83,6 +84,7 @@ void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)
while (!list_empty(&__bridge.transactions))
cpu_relax();
}
EXPORT_SYMBOL(vexpress_config_bridge_unregister);
struct vexpress_config_func {
......@@ -142,6 +144,7 @@ struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
return func;
}
EXPORT_SYMBOL(__vexpress_config_func_get);
void vexpress_config_func_put(struct vexpress_config_func *func)
{
......@@ -149,7 +152,7 @@ void vexpress_config_func_put(struct vexpress_config_func *func)
of_node_put(func->bridge->node);
kfree(func);
}
EXPORT_SYMBOL(vexpress_config_func_put);
struct vexpress_config_trans {
struct vexpress_config_func *func;
......@@ -229,6 +232,7 @@ void vexpress_config_complete(struct vexpress_config_bridge *bridge,
complete(&trans->completion);
}
EXPORT_SYMBOL(vexpress_config_complete);
int vexpress_config_wait(struct vexpress_config_trans *trans)
{
......@@ -236,7 +240,7 @@ int vexpress_config_wait(struct vexpress_config_trans *trans)
return trans->status;
}
EXPORT_SYMBOL(vexpress_config_wait);
int vexpress_config_read(struct vexpress_config_func *func, int offset,
u32 *data)
......
......@@ -1882,7 +1882,7 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
}
}
#define WM5102_MAX_REGISTER 0x1a8fff
#define WM5102_MAX_REGISTER 0x1a9800
const struct regmap_config wm5102_spi_regmap = {
.reg_bits = 32,
......
......@@ -1060,26 +1060,6 @@ static int sd_wait_voltage_stable_2(struct realtek_pci_sdmmc *host)
return 0;
}
static int sd_change_bank_voltage(struct realtek_pci_sdmmc *host, u8 voltage)
{
struct rtsx_pcr *pcr = host->pcr;
int err;
if (voltage == SD_IO_3V3) {
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
if (err < 0)
return err;
} else if (voltage == SD_IO_1V8) {
err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
if (err < 0)
return err;
} else {
return -EINVAL;
}
return 0;
}
static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct realtek_pci_sdmmc *host = mmc_priv(mmc);
......@@ -1098,11 +1078,11 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
rtsx_pci_start_run(pcr);
if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
voltage = SD_IO_3V3;
voltage = OUTPUT_3V3;
else
voltage = SD_IO_1V8;
voltage = OUTPUT_1V8;
if (voltage == SD_IO_1V8) {
if (voltage == OUTPUT_1V8) {
err = rtsx_pci_write_register(pcr,
SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
if (err < 0)
......@@ -1113,11 +1093,11 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
goto out;
}
err = sd_change_bank_voltage(host, voltage);