MFD Fixes for 3.5
- 3 Palmas fixes, 1 of them being a build error fix. - 2 mc13xx fixes. 1 for fixing an SPI regmap configuration and another one for working around an i.Mx hardware bug. - 1 omap-usb regression fix. - 1 twl6040 build breakage fix. - 1 file deletion (ab5500-core.h) that was overlooked during the last merge window. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJP/vIeAAoJEIqAPN1PVmxKTlMP/RFiIP9Exyy0gqGCMJpYpOfH m1NX0LMZ9ktv61M0bgx1AZewNCLG0O6vNf1zW6S4aaczx/D5o1uqWTrra7WqIHTj LG2dTpm1dYo2FHNkaGSwpDCGJI2H1K9l4HBcevJcNeVsE3OSZIfQXOFAdXuxJjf3 RUBZ/dzRAi0/KnZySu+1z3ua3Fbican5CwcljsMEp3K5ajr/d7zFCYDz3Osk+g3k kvncHZtfeQNhXgfHMm+8nWRnHvpGWutUXtAIL5yzSQgeEtKANe7D2KsxK73t68iV BkelhzqXk9o711nluA0hF4gvS20/cS675QNbQ6XLUK2N7wsCORqMSTNXxnvJze2E 1hH599dLqPMkq3P5TRCTaQLx8p/QK8Vnrgvsy5pOkSZnqiNU/Owtik0NA4Gz3WrG f6WMRHNb+wwLdvhkqHUuMjt2OzmIUiuikKu6kt2pyJ3tXj0tPisC0UieF+6fRHG+ yxwrXqKtv/aj+gbp+X476fMWt2LR4Duihq1QkW2tE9rtkVlUMTIJgCj6T1mdC6T5 g1ELR3mi+AXCyOp5d6jpmJmKTnHjQfCPouNgalfFonJlp7Fngih0SzUpwV/XYyP7 CUy490mcRUZUhSmTH4UQV9CfxhQA8gKNbN9Oak499N6UNWSDyoiH/bh+h/BQuAli Gn6cYgk5IKYjiO020ilG =dlI4 -----END PGP SIGNATURE----- Merge tag 'mfd-for-linus-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6 Pull MFD Fixes from Samuel Ortiz: - Three Palmas fixes, One of them being a build error fix. - Two mc13xx fixes. One for fixing an SPI regmap configuration and another one for working around an i.Mx hardware bug. - One omap-usb regression fix. - One twl6040 build breakage fix. - One file deletion (ab5500-core.h) that was overlooked during the last merge window. * tag 'mfd-for-linus-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: mfd: Add missing hunk to change palmas irq to clear on read mfd: Fix palmas regulator pdata missing mfd: USB: Fix the omap-usb EHCI ULPI PHY reset fix issues. mfd: Update twl6040 Kconfig to avoid build breakage mfd: Delete ab5500-core.h mfd: mc13xxx workaround SPI hardware bug on i.Mx mfd: Fix mc13xxx SPI regmap mfd: Add terminating entry for i2c_device_id palmas table
This commit is contained in:
commit
7801dc33be
@ -286,6 +286,7 @@ config TWL6040_CORE
|
||||
depends on I2C=y && GENERIC_HARDIRQS
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select IRQ_DOMAIN
|
||||
default n
|
||||
help
|
||||
Say yes here if you want support for Texas Instruments TWL6040 audio
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 ST-Ericsson
|
||||
* License terms: GNU General Public License (GPL) version 2
|
||||
* Shared definitions and data structures for the AB5500 MFD driver
|
||||
*/
|
||||
|
||||
/* Read/write operation values. */
|
||||
#define AB5500_PERM_RD (0x01)
|
||||
#define AB5500_PERM_WR (0x02)
|
||||
|
||||
/* Read/write permissions. */
|
||||
#define AB5500_PERM_RO (AB5500_PERM_RD)
|
||||
#define AB5500_PERM_RW (AB5500_PERM_RD | AB5500_PERM_WR)
|
||||
|
||||
#define AB5500_MASK_BASE (0x60)
|
||||
#define AB5500_MASK_END (0x79)
|
||||
#define AB5500_CHIP_ID (0x20)
|
||||
|
||||
/**
|
||||
* struct ab5500_reg_range
|
||||
* @first: the first address of the range
|
||||
* @last: the last address of the range
|
||||
* @perm: access permissions for the range
|
||||
*/
|
||||
struct ab5500_reg_range {
|
||||
u8 first;
|
||||
u8 last;
|
||||
u8 perm;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ab5500_i2c_ranges
|
||||
* @count: the number of ranges in the list
|
||||
* @range: the list of register ranges
|
||||
*/
|
||||
struct ab5500_i2c_ranges {
|
||||
u8 nranges;
|
||||
u8 bankid;
|
||||
const struct ab5500_reg_range *range;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ab5500_i2c_banks
|
||||
* @count: the number of ranges in the list
|
||||
* @range: the list of register ranges
|
||||
*/
|
||||
struct ab5500_i2c_banks {
|
||||
u8 nbanks;
|
||||
const struct ab5500_i2c_ranges *bank;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ab5500_bank
|
||||
* @slave_addr: I2C slave_addr found in AB5500 specification
|
||||
* @name: Documentation name of the bank. For reference
|
||||
*/
|
||||
struct ab5500_bank {
|
||||
u8 slave_addr;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const struct ab5500_bank bankinfo[AB5500_NUM_BANKS] = {
|
||||
[AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = {
|
||||
AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP, "VIT_IO_I2C_CLK_TST_OTP"},
|
||||
[AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = {
|
||||
AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST, "VDDDIG_IO_I2C_CLK_TST"},
|
||||
[AB5500_BANK_VDENC] = {AB5500_ADDR_VDENC, "VDENC"},
|
||||
[AB5500_BANK_SIM_USBSIM] = {AB5500_ADDR_SIM_USBSIM, "SIM_USBSIM"},
|
||||
[AB5500_BANK_LED] = {AB5500_ADDR_LED, "LED"},
|
||||
[AB5500_BANK_ADC] = {AB5500_ADDR_ADC, "ADC"},
|
||||
[AB5500_BANK_RTC] = {AB5500_ADDR_RTC, "RTC"},
|
||||
[AB5500_BANK_STARTUP] = {AB5500_ADDR_STARTUP, "STARTUP"},
|
||||
[AB5500_BANK_DBI_ECI] = {AB5500_ADDR_DBI_ECI, "DBI-ECI"},
|
||||
[AB5500_BANK_CHG] = {AB5500_ADDR_CHG, "CHG"},
|
||||
[AB5500_BANK_FG_BATTCOM_ACC] = {
|
||||
AB5500_ADDR_FG_BATTCOM_ACC, "FG_BATCOM_ACC"},
|
||||
[AB5500_BANK_USB] = {AB5500_ADDR_USB, "USB"},
|
||||
[AB5500_BANK_IT] = {AB5500_ADDR_IT, "IT"},
|
||||
[AB5500_BANK_VIBRA] = {AB5500_ADDR_VIBRA, "VIBRA"},
|
||||
[AB5500_BANK_AUDIO_HEADSETUSB] = {
|
||||
AB5500_ADDR_AUDIO_HEADSETUSB, "AUDIO_HEADSETUSB"},
|
||||
};
|
||||
|
||||
int ab5500_get_register_interruptible_raw(struct ab5500 *ab, u8 bank, u8 reg,
|
||||
u8 *value);
|
||||
int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank,
|
||||
u8 reg, u8 bitmask, u8 bitvalues);
|
@ -49,10 +49,72 @@ static struct regmap_config mc13xxx_regmap_spi_config = {
|
||||
.reg_bits = 7,
|
||||
.pad_bits = 1,
|
||||
.val_bits = 24,
|
||||
.write_flag_mask = 0x80,
|
||||
|
||||
.max_register = MC13XXX_NUMREGS,
|
||||
|
||||
.cache_type = REGCACHE_NONE,
|
||||
.use_single_rw = 1,
|
||||
};
|
||||
|
||||
static int mc13xxx_spi_read(void *context, const void *reg, size_t reg_size,
|
||||
void *val, size_t val_size)
|
||||
{
|
||||
unsigned char w[4] = { *((unsigned char *) reg), 0, 0, 0};
|
||||
unsigned char r[4];
|
||||
unsigned char *p = val;
|
||||
struct device *dev = context;
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
struct spi_transfer t = {
|
||||
.tx_buf = w,
|
||||
.rx_buf = r,
|
||||
.len = 4,
|
||||
};
|
||||
|
||||
struct spi_message m;
|
||||
int ret;
|
||||
|
||||
if (val_size != 3 || reg_size != 1)
|
||||
return -ENOTSUPP;
|
||||
|
||||
spi_message_init(&m);
|
||||
spi_message_add_tail(&t, &m);
|
||||
ret = spi_sync(spi, &m);
|
||||
|
||||
memcpy(p, &r[1], 3);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mc13xxx_spi_write(void *context, const void *data, size_t count)
|
||||
{
|
||||
struct device *dev = context;
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
|
||||
if (count != 4)
|
||||
return -ENOTSUPP;
|
||||
|
||||
return spi_write(spi, data, count);
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot use regmap-spi generic bus implementation here.
|
||||
* The MC13783 chip will get corrupted if CS signal is deasserted
|
||||
* and on i.Mx31 SoC (the target SoC for MC13783 PMIC) the SPI controller
|
||||
* has the following errata (DSPhl22960):
|
||||
* "The CSPI negates SS when the FIFO becomes empty with
|
||||
* SSCTL= 0. Software cannot guarantee that the FIFO will not
|
||||
* drain because of higher priority interrupts and the
|
||||
* non-realtime characteristics of the operating system. As a
|
||||
* result, the SS will negate before all of the data has been
|
||||
* transferred to/from the peripheral."
|
||||
* We workaround this by accessing the SPI controller with a
|
||||
* single transfert.
|
||||
*/
|
||||
|
||||
static struct regmap_bus regmap_mc13xxx_bus = {
|
||||
.write = mc13xxx_spi_write,
|
||||
.read = mc13xxx_spi_read,
|
||||
};
|
||||
|
||||
static int mc13xxx_spi_probe(struct spi_device *spi)
|
||||
@ -73,12 +135,13 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
|
||||
|
||||
dev_set_drvdata(&spi->dev, mc13xxx);
|
||||
spi->mode = SPI_MODE_0 | SPI_CS_HIGH;
|
||||
spi->bits_per_word = 32;
|
||||
|
||||
mc13xxx->dev = &spi->dev;
|
||||
mutex_init(&mc13xxx->lock);
|
||||
|
||||
mc13xxx->regmap = regmap_init_spi(spi, &mc13xxx_regmap_spi_config);
|
||||
mc13xxx->regmap = regmap_init(&spi->dev, ®map_mc13xxx_bus, &spi->dev,
|
||||
&mc13xxx_regmap_spi_config);
|
||||
|
||||
if (IS_ERR(mc13xxx->regmap)) {
|
||||
ret = PTR_ERR(mc13xxx->regmap);
|
||||
dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n",
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/usb.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
@ -500,8 +501,21 @@ static void omap_usbhs_init(struct device *dev)
|
||||
dev_dbg(dev, "starting TI HSUSB Controller\n");
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
spin_lock_irqsave(&omap->lock, flags);
|
||||
|
||||
if (pdata->ehci_data->phy_reset) {
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
|
||||
gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
|
||||
GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
|
||||
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
|
||||
gpio_request_one(pdata->ehci_data->reset_gpio_port[1],
|
||||
GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
|
||||
|
||||
/* Hold the PHY in RESET for enough time till DIR is high */
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&omap->lock, flags);
|
||||
omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
|
||||
dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
|
||||
|
||||
@ -581,9 +595,39 @@ static void omap_usbhs_init(struct device *dev)
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&omap->lock, flags);
|
||||
|
||||
if (pdata->ehci_data->phy_reset) {
|
||||
/* Hold the PHY in RESET for enough time till
|
||||
* PHY is settled and ready
|
||||
*/
|
||||
udelay(10);
|
||||
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
|
||||
gpio_set_value_cansleep
|
||||
(pdata->ehci_data->reset_gpio_port[0], 1);
|
||||
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
|
||||
gpio_set_value_cansleep
|
||||
(pdata->ehci_data->reset_gpio_port[1], 1);
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
}
|
||||
|
||||
static void omap_usbhs_deinit(struct device *dev)
|
||||
{
|
||||
struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
|
||||
struct usbhs_omap_platform_data *pdata = &omap->platdata;
|
||||
|
||||
if (pdata->ehci_data->phy_reset) {
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
|
||||
gpio_free(pdata->ehci_data->reset_gpio_port[0]);
|
||||
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
|
||||
gpio_free(pdata->ehci_data->reset_gpio_port[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* usbhs_omap_probe - initialize TI-based HCDs
|
||||
@ -767,6 +811,7 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
|
||||
goto end_probe;
|
||||
|
||||
err_alloc:
|
||||
omap_usbhs_deinit(&pdev->dev);
|
||||
iounmap(omap->tll_base);
|
||||
|
||||
err_tll:
|
||||
@ -818,6 +863,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
|
||||
|
||||
omap_usbhs_deinit(&pdev->dev);
|
||||
iounmap(omap->tll_base);
|
||||
iounmap(omap->uhh_base);
|
||||
clk_put(omap->init_60m_fclk);
|
||||
|
@ -356,7 +356,14 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(palmas->regmap[1], palmas->irq,
|
||||
/* Change IRQ into clear on read mode for efficiency */
|
||||
slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE);
|
||||
addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL);
|
||||
reg = PALMAS_INT_CTRL_INT_CLEAR;
|
||||
|
||||
regmap_write(palmas->regmap[slave], addr, reg);
|
||||
|
||||
ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
|
||||
IRQF_ONESHOT | IRQF_TRIGGER_LOW, -1, &palmas_irq_chip,
|
||||
&palmas->irq_data);
|
||||
if (ret < 0)
|
||||
@ -441,6 +448,9 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
|
||||
goto err;
|
||||
}
|
||||
|
||||
children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata;
|
||||
children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata);
|
||||
|
||||
ret = mfd_add_devices(palmas->dev, -1,
|
||||
children, ARRAY_SIZE(palmas_children),
|
||||
NULL, regmap_irq_chip_get_base(palmas->irq_data));
|
||||
@ -472,6 +482,7 @@ static const struct i2c_device_id palmas_i2c_id[] = {
|
||||
{ "twl6035", },
|
||||
{ "twl6037", },
|
||||
{ "tps65913", },
|
||||
{ /* end */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, palmas_i2c_id);
|
||||
|
||||
|
@ -281,14 +281,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
/* Hold PHYs in reset while initializing EHCI controller */
|
||||
if (pdata->phy_reset) {
|
||||
if (gpio_is_valid(pdata->reset_gpio_port[0]))
|
||||
gpio_request_one(pdata->reset_gpio_port[0],
|
||||
GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
|
||||
gpio_set_value_cansleep(pdata->reset_gpio_port[0], 0);
|
||||
|
||||
if (gpio_is_valid(pdata->reset_gpio_port[1]))
|
||||
gpio_request_one(pdata->reset_gpio_port[1],
|
||||
GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
|
||||
gpio_set_value_cansleep(pdata->reset_gpio_port[1], 0);
|
||||
|
||||
/* Hold the PHY in RESET for enough time till DIR is high */
|
||||
udelay(10);
|
||||
@ -330,6 +329,11 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
|
||||
omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params);
|
||||
|
||||
ehci_reset(omap_ehci);
|
||||
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to add hcd with err %d\n", ret);
|
||||
goto err_add_hcd;
|
||||
}
|
||||
|
||||
if (pdata->phy_reset) {
|
||||
/* Hold the PHY in RESET for enough time till
|
||||
@ -344,12 +348,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
|
||||
gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1);
|
||||
}
|
||||
|
||||
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to add hcd with err %d\n", ret);
|
||||
goto err_add_hcd;
|
||||
}
|
||||
|
||||
/* root ports should always stay powered */
|
||||
ehci_port_power(omap_ehci, 1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user