Skip to content

Commit

Permalink
Merge tag 'mfd-for-linus-3.5' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/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
  • Loading branch information
Linus Torvalds committed Jul 13, 2012
2 parents 68394bf + b330f85 commit 7801dc3
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 101 deletions.
1 change: 1 addition & 0 deletions drivers/mfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
87 changes: 0 additions & 87 deletions drivers/mfd/ab5500-core.h

This file was deleted.

67 changes: 65 additions & 2 deletions drivers/mfd/mc13xxx-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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, &regmap_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",
Expand Down
48 changes: 47 additions & 1 deletion drivers/mfd/omap-usb-host.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down
13 changes: 12 additions & 1 deletion drivers/mfd/palmas.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -472,6 +482,7 @@ static const struct i2c_device_id palmas_i2c_id[] = {
{ "twl6035", },
{ "twl6037", },
{ "tps65913", },
{ /* end */ }
};
MODULE_DEVICE_TABLE(i2c, palmas_i2c_id);

Expand Down
18 changes: 8 additions & 10 deletions drivers/usb/host/ehci-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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);

Expand Down

0 comments on commit 7801dc3

Please sign in to comment.