Commit 06e23d51 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'mfd-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "Core Framework:
   - New API to call bespoke pre/post IRQ handlers; Regmap

  New Device Support:
   - Add support for RN5T567 to rn5t618
   - Add support for COMe-cSL6 and COMe-mAL10 to kempld-core

  New Functionality:
   - Add support for USB Power Supply to axp20x
   - Add support for Power Key to hi655x-pmic

  Fix-ups:
   - Update MAINTAINERS; Dialog, Altera
   - Remove module support; max77843, max77620, max8998, max8997, max8925-i2c
   - Add module support; max14577
   - Constifying; max77620
   - Allow bespoke IRQ masking/unmasking; max77620
   - Remove superfluous code; arizona, qcom_rpm, smsc-ece1099
   - Power Management fixups; arizona-core
   - Error-path improvement; twl-core, dm355evm_msp, smsc-ece1099, hi655x
   - Clocking fixups; twl6040
   - Trivial (spelling, headers, coding-style, whitespace, (re)naming);
       si476x-i2c, omap-usb-tll, ti_am335x_tscadc, tps6507, hi655x-pmic

  Bug Fixes:
   - Fix offset error for MSM8660; qcom_rpm
   - Fix possible spurious IRQs; arizona, hi655x-pmic"

* tag 'mfd-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (42 commits)
  mfd: qcom_rpm: Parametrize also ack selector size
  mfd: twl6040: Handle mclk used for HPPLL and optional internal clock source
  mfd: Add support for COMe-cSL6 and COMe-mAL10 to Kontron PLD driver
  mfd: hi655x: Fix return value check in hi655x_pmic_probe()
  mfd: smsc-ece1099: Return directly after a function failure in smsc_i2c_probe()
  mfd: smsc-ece1099: Delete an unnecessary variable initialisation in smsc_i2c_probe()
  mfd: dm355evm_msp: Return directly after a failed platform_device_alloc() in add_child()
  mfd: twl-core: Refactoring for add_numbered_child()
  mfd: twl-core: Return directly after a failed platform_device_alloc() in add_numbered_child()
  mfd: arizona: Add missing disable of PM runtime on probe error path
  mfd: stmpe: Move platform data into MFD driver
  mfd: max14577: Allow driver to be built as a module
  mfd: max14577: Use module_init() instead of subsys_initcall()
  mfd: arizona: Remove some duplicate defines
  mfd: qcom_rpm: Remove unused define
  mfd: hi655x-pmic: Add powerkey device to hi655x PMIC driver
  mfd: hi655x-pmic: Rename some interrupt macro names
  mfd: hi655x-pmic: Fixup issue with un-acked interrupts
  mfd: arizona: Check if AOD interrupts are pending before dispatching
  mfd: qcom_rpm: Fix offset error for msm8660
  ...
parents dd967117 f37be01e
...@@ -19,8 +19,8 @@ Required properties: ...@@ -19,8 +19,8 @@ Required properties:
Optional properties, nodes: Optional properties, nodes:
- enable-active-high: To power on the twl6040 during boot. - enable-active-high: To power on the twl6040 during boot.
- clocks: phandle to the clk32k clock provider - clocks: phandle to the clk32k and/or to mclk clock provider
- clock-names: Must be "clk32k" - clock-names: Must be "clk32k" for the 32K clock and "mclk" for the MCLK.
Vibra functionality Vibra functionality
Required properties: Required properties:
......
...@@ -612,6 +612,13 @@ L: linux-gpio@vger.kernel.org ...@@ -612,6 +612,13 @@ L: linux-gpio@vger.kernel.org
S: Maintained S: Maintained
F: drivers/gpio/gpio-altera.c F: drivers/gpio/gpio-altera.c
ALTERA SYSTEM RESOURCE DRIVER FOR ARRIA10 DEVKIT
M: Thor Thayer <tthayer@opensource.altera.com>
S: Maintained
F: drivers/gpio/gpio-altera-a10sr.c
F: drivers/mfd/altera-a10sr.c
F: include/linux/mfd/altera-a10sr.h
ALTERA TRIPLE SPEED ETHERNET DRIVER ALTERA TRIPLE SPEED ETHERNET DRIVER
M: Vince Bridgers <vbridger@opensource.altera.com> M: Vince Bridgers <vbridger@opensource.altera.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
...@@ -3711,6 +3718,8 @@ M: Support Opensource <support.opensource@diasemi.com> ...@@ -3711,6 +3718,8 @@ M: Support Opensource <support.opensource@diasemi.com>
W: http://www.dialog-semiconductor.com/products W: http://www.dialog-semiconductor.com/products
S: Supported S: Supported
F: Documentation/hwmon/da90?? F: Documentation/hwmon/da90??
F: Documentation/devicetree/bindings/mfd/da90*.txt
F: Documentation/devicetree/bindings/regulator/da92*.txt
F: Documentation/devicetree/bindings/sound/da[79]*.txt F: Documentation/devicetree/bindings/sound/da[79]*.txt
F: drivers/gpio/gpio-da90??.c F: drivers/gpio/gpio-da90??.c
F: drivers/hwmon/da90??-hwmon.c F: drivers/hwmon/da90??-hwmon.c
...@@ -3731,8 +3740,10 @@ F: drivers/watchdog/da90??_wdt.c ...@@ -3731,8 +3740,10 @@ F: drivers/watchdog/da90??_wdt.c
F: include/linux/mfd/da903x.h F: include/linux/mfd/da903x.h
F: include/linux/mfd/da9052/ F: include/linux/mfd/da9052/
F: include/linux/mfd/da9055/ F: include/linux/mfd/da9055/
F: include/linux/mfd/da9062/
F: include/linux/mfd/da9063/ F: include/linux/mfd/da9063/
F: include/linux/mfd/da9150/ F: include/linux/mfd/da9150/
F: include/linux/regulator/da9211.h
F: include/sound/da[79]*.h F: include/sound/da[79]*.h
F: sound/soc/codecs/da[79]*.[ch] F: sound/soc/codecs/da[79]*.[ch]
......
...@@ -18,6 +18,17 @@ config MFD_CS5535 ...@@ -18,6 +18,17 @@ config MFD_CS5535
This is the core driver for CS5535/CS5536 MFD functions. This is This is the core driver for CS5535/CS5536 MFD functions. This is
necessary for using the board's GPIO and MFGPT functionality. necessary for using the board's GPIO and MFGPT functionality.
config MFD_ALTERA_A10SR
bool "Altera Arria10 DevKit System Resource chip"
depends on ARCH_SOCFPGA && SPI_MASTER=y && OF
select REGMAP_SPI
select MFD_CORE
help
Support for the Altera Arria10 DevKit MAX5 System Resource chip
using the SPI interface. This driver provides common support for
accessing the external gpio extender (LEDs & buttons) and
power supply alarms (hwmon).
config MFD_ACT8945A config MFD_ACT8945A
tristate "Active-semi ACT8945A" tristate "Active-semi ACT8945A"
select MFD_CORE select MFD_CORE
...@@ -480,6 +491,8 @@ config MFD_KEMPLD ...@@ -480,6 +491,8 @@ config MFD_KEMPLD
* COMe-cDC2 (microETXexpress-DC) * COMe-cDC2 (microETXexpress-DC)
* COMe-cHL6 * COMe-cHL6
* COMe-cPC2 (microETXexpress-PC) * COMe-cPC2 (microETXexpress-PC)
* COMe-cSL6
* COMe-mAL10
* COMe-mBT10 * COMe-mBT10
* COMe-mCT10 * COMe-mCT10
* COMe-mTT10 (nanoETXexpress-TT) * COMe-mTT10 (nanoETXexpress-TT)
...@@ -524,8 +537,8 @@ config MFD_88PM860X ...@@ -524,8 +537,8 @@ config MFD_88PM860X
battery-charger under the corresponding menus. battery-charger under the corresponding menus.
config MFD_MAX14577 config MFD_MAX14577
bool "Maxim Semiconductor MAX14577/77836 MUIC + Charger Support" tristate "Maxim Semiconductor MAX14577/77836 MUIC + Charger Support"
depends on I2C=y depends on I2C
select MFD_CORE select MFD_CORE
select REGMAP_I2C select REGMAP_I2C
select REGMAP_IRQ select REGMAP_IRQ
......
...@@ -205,3 +205,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o ...@@ -205,3 +205,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
/*
* Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPI access for Altera Arria10 MAX5 System Resource Chip
*
* Adapted from DA9052
*/
#include <linux/mfd/altera-a10sr.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/spi/spi.h>
static const struct mfd_cell altr_a10sr_subdev_info[] = {
{
.name = "altr_a10sr_gpio",
.of_compatible = "altr,a10sr-gpio",
},
};
static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)
{
switch (reg) {
case ALTR_A10SR_VERSION_READ:
case ALTR_A10SR_LED_REG:
case ALTR_A10SR_PBDSW_REG:
case ALTR_A10SR_PBDSW_IRQ_REG:
case ALTR_A10SR_PWR_GOOD1_REG:
case ALTR_A10SR_PWR_GOOD2_REG:
case ALTR_A10SR_PWR_GOOD3_REG:
case ALTR_A10SR_FMCAB_REG:
case ALTR_A10SR_HPS_RST_REG:
case ALTR_A10SR_USB_QSPI_REG:
case ALTR_A10SR_SFPA_REG:
case ALTR_A10SR_SFPB_REG:
case ALTR_A10SR_I2C_M_REG:
case ALTR_A10SR_WARM_RST_REG:
case ALTR_A10SR_WR_KEY_REG:
case ALTR_A10SR_PMBUS_REG:
return true;
default:
return false;
}
}
static bool altr_a10sr_reg_writeable(struct device *dev, unsigned int reg)
{
switch (reg) {
case ALTR_A10SR_LED_REG:
case ALTR_A10SR_PBDSW_IRQ_REG:
case ALTR_A10SR_FMCAB_REG:
case ALTR_A10SR_HPS_RST_REG:
case ALTR_A10SR_USB_QSPI_REG:
case ALTR_A10SR_SFPA_REG:
case ALTR_A10SR_SFPB_REG:
case ALTR_A10SR_WARM_RST_REG:
case ALTR_A10SR_WR_KEY_REG:
case ALTR_A10SR_PMBUS_REG:
return true;
default:
return false;
}
}
static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
case ALTR_A10SR_PBDSW_REG:
case ALTR_A10SR_PBDSW_IRQ_REG:
case ALTR_A10SR_PWR_GOOD1_REG:
case ALTR_A10SR_PWR_GOOD2_REG:
case ALTR_A10SR_PWR_GOOD3_REG:
case ALTR_A10SR_HPS_RST_REG:
case ALTR_A10SR_I2C_M_REG:
case ALTR_A10SR_WARM_RST_REG:
case ALTR_A10SR_WR_KEY_REG:
case ALTR_A10SR_PMBUS_REG:
return true;
default:
return false;
}
}
const struct regmap_config altr_a10sr_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_NONE,
.use_single_rw = true,
.read_flag_mask = 1,
.write_flag_mask = 0,
.max_register = ALTR_A10SR_WR_KEY_REG,
.readable_reg = altr_a10sr_reg_readable,
.writeable_reg = altr_a10sr_reg_writeable,
.volatile_reg = altr_a10sr_reg_volatile,
};
static int altr_a10sr_spi_probe(struct spi_device *spi)
{
int ret;
struct altr_a10sr *a10sr;
a10sr = devm_kzalloc(&spi->dev, sizeof(*a10sr),
GFP_KERNEL);
if (!a10sr)
return -ENOMEM;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 8;
spi_setup(spi);
a10sr->dev = &spi->dev;
spi_set_drvdata(spi, a10sr);
a10sr->regmap = devm_regmap_init_spi(spi, &altr_a10sr_regmap_config);
if (IS_ERR(a10sr->regmap)) {
ret = PTR_ERR(a10sr->regmap);
dev_err(&spi->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
}
ret = devm_mfd_add_devices(a10sr->dev, PLATFORM_DEVID_AUTO,
altr_a10sr_subdev_info,
ARRAY_SIZE(altr_a10sr_subdev_info),
NULL, 0, NULL);
if (ret)
dev_err(a10sr->dev, "Failed to register sub-devices: %d\n",
ret);
return ret;
}
static const struct of_device_id altr_a10sr_spi_of_match[] = {
{ .compatible = "altr,a10sr" },
{ },
};
MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match);
static struct spi_driver altr_a10sr_spi_driver = {
.probe = altr_a10sr_spi_probe,
.driver = {
.name = "altr_a10sr",
.of_match_table = of_match_ptr(altr_a10sr_spi_of_match),
},
};
module_spi_driver(altr_a10sr_spi_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>");
MODULE_DESCRIPTION("Altera Arria10 DevKit System Resource MFD Driver");
...@@ -1462,7 +1462,7 @@ int arizona_dev_init(struct arizona *arizona) ...@@ -1462,7 +1462,7 @@ int arizona_dev_init(struct arizona *arizona)
/* Set up for interrupts */ /* Set up for interrupts */
ret = arizona_irq_init(arizona); ret = arizona_irq_init(arizona);
if (ret != 0) if (ret != 0)
goto err_reset; goto err_pm;
pm_runtime_set_autosuspend_delay(arizona->dev, 100); pm_runtime_set_autosuspend_delay(arizona->dev, 100);
pm_runtime_use_autosuspend(arizona->dev); pm_runtime_use_autosuspend(arizona->dev);
...@@ -1486,6 +1486,8 @@ int arizona_dev_init(struct arizona *arizona) ...@@ -1486,6 +1486,8 @@ int arizona_dev_init(struct arizona *arizona)
err_irq: err_irq:
arizona_irq_exit(arizona); arizona_irq_exit(arizona);
err_pm:
pm_runtime_disable(arizona->dev);
err_reset: err_reset:
arizona_enable_reset(arizona); arizona_enable_reset(arizona);
regulator_disable(arizona->dcvdd); regulator_disable(arizona->dcvdd);
......
...@@ -109,8 +109,20 @@ static irqreturn_t arizona_irq_thread(int irq, void *data) ...@@ -109,8 +109,20 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
do { do {
poll = false; poll = false;
if (arizona->aod_irq_chip) if (arizona->aod_irq_chip) {
handle_nested_irq(irq_find_mapping(arizona->virq, 0)); /*
* Check the AOD status register to determine whether
* the nested IRQ handler should be called.
*/
ret = regmap_read(arizona->regmap,
ARIZONA_AOD_IRQ1, &val);
if (ret)
dev_warn(arizona->dev,
"Failed to read AOD IRQ1 %d\n", ret);
else if (val)
handle_nested_irq(
irq_find_mapping(arizona->virq, 0));
}
/* /*
* Check if one of the main interrupts is asserted and only * Check if one of the main interrupts is asserted and only
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
#include <linux/err.h> #include <linux/err.h>
#include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -93,7 +94,10 @@ static const struct regmap_range axp22x_writeable_ranges[] = { ...@@ -93,7 +94,10 @@ static const struct regmap_range axp22x_writeable_ranges[] = {
}; };
static const struct regmap_range axp22x_volatile_ranges[] = { static const struct regmap_range axp22x_volatile_ranges[] = {
regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE), regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
}; };
static const struct regmap_access_table axp22x_writeable_table = { static const struct regmap_access_table axp22x_writeable_table = {
...@@ -157,6 +161,11 @@ static struct resource axp20x_usb_power_supply_resources[] = { ...@@ -157,6 +161,11 @@ static struct resource axp20x_usb_power_supply_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"), DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
}; };
static struct resource axp22x_usb_power_supply_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
};
static struct resource axp22x_pek_resources[] = { static struct resource axp22x_pek_resources[] = {
{ {
.name = "PEK_DBR", .name = "PEK_DBR",
...@@ -524,6 +533,11 @@ static struct mfd_cell axp22x_cells[] = { ...@@ -524,6 +533,11 @@ static struct mfd_cell axp22x_cells[] = {
.resources = axp22x_pek_resources, .resources = axp22x_pek_resources,
}, { }, {
.name = "axp20x-regulator", .name = "axp20x-regulator",
}, {
.name = "axp20x-usb-power-supply",
.of_compatible = "x-powers,axp221-usb-power-supply",
.num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
.resources = axp22x_usb_power_supply_resources,
}, },
}; };
...@@ -664,6 +678,9 @@ static void axp20x_power_off(void) ...@@ -664,6 +678,9 @@ static void axp20x_power_off(void)
regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
AXP20X_OFF); AXP20X_OFF);
/* Give capacitors etc. time to drain to avoid kernel panic msg. */
msleep(500);
} }
int axp20x_match_device(struct axp20x_dev *axp20x) int axp20x_match_device(struct axp20x_dev *axp20x)
......
...@@ -199,11 +199,8 @@ static struct device *add_child(struct i2c_client *client, const char *name, ...@@ -199,11 +199,8 @@ static struct device *add_child(struct i2c_client *client, const char *name,
int status; int status;
pdev = platform_device_alloc(name, -1); pdev = platform_device_alloc(name, -1);
if (!pdev) { if (!pdev)
dev_dbg(&client->dev, "can't alloc dev\n"); return ERR_PTR(-ENOMEM);
status = -ENOMEM;
goto err;
}
device_init_wakeup(&pdev->dev, can_wakeup); device_init_wakeup(&pdev->dev, can_wakeup);
pdev->dev.parent = &client->dev; pdev->dev.parent = &client->dev;
......
...@@ -24,19 +24,15 @@ ...@@ -24,19 +24,15 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
static const struct mfd_cell hi655x_pmic_devs[] = {
{ .name = "hi655x-regulator", },
};
static const struct regmap_irq hi655x_irqs[] = { static const struct regmap_irq hi655x_irqs[] = {
{ .reg_offset = 0, .mask = OTMP_D1R_INT }, { .reg_offset = 0, .mask = OTMP_D1R_INT_MASK },
{ .reg_offset = 0, .mask = VSYS_2P5_R_INT }, { .reg_offset = 0, .mask = VSYS_2P5_R_INT_MASK },
{ .reg_offset = 0, .mask = VSYS_UV_D3R_INT }, { .reg_offset = 0, .mask = VSYS_UV_D3R_INT_MASK },
{ .reg_offset = 0, .mask = VSYS_6P0_D200UR_INT }, { .reg_offset = 0, .mask = VSYS_6P0_D200UR_INT_MASK },
{ .reg_offset = 0, .mask = PWRON_D4SR_INT }, { .reg_offset = 0, .mask = PWRON_D4SR_INT_MASK },
{ .reg_offset = 0, .mask = PWRON_D20F_INT }, { .reg_offset = 0, .mask = PWRON_D20F_INT_MASK },
{ .reg_offset = 0, .mask = PWRON_D20R_INT }, { .reg_offset = 0, .mask = PWRON_D20R_INT_MASK },
{ .reg_offset = 0, .mask = RESERVE_INT }, { .reg_offset = 0, .mask = RESERVE_INT_MASK },
}; };
static const struct regmap_irq_chip hi655x_irq_chip = { static const struct regmap_irq_chip hi655x_irq_chip = {
...@@ -45,6 +41,7 @@ static const struct regmap_irq_chip hi655x_irq_chip = { ...@@ -45,6 +41,7 @@ static const struct regmap_irq_chip hi655x_irq_chip = {
.num_regs = 1, .num_regs = 1,
.num_irqs = ARRAY_SIZE(hi655x_irqs), .num_irqs = ARRAY_SIZE(hi655x_irqs),
.status_base = HI655X_IRQ_STAT_BASE, .status_base = HI655X_IRQ_STAT_BASE,
.ack_base = HI655X_IRQ_STAT_BASE,
.mask_base = HI655X_IRQ_MASK_BASE, .mask_base = HI655X_IRQ_MASK_BASE,
}; };
...@@ -55,6 +52,34 @@ static struct regmap_config hi655x_regmap_config = { ...@@ -55,6 +52,34 @@ static struct regmap_config hi655x_regmap_config = {
.max_register = HI655X_BUS_ADDR(0xFFF), .max_register = HI655X_BUS_ADDR(0xFFF),
}; };
static struct resource pwrkey_resources[] = {
{
.name = "down",
.start = PWRON_D20R_INT,
.end = PWRON_D20R_INT,
.flags = IORESOURCE_IRQ,
}, {
.name = "up",
.start = PWRON_D20F_INT,
.end = PWRON_D20F_INT,
.flags = IORESOURCE_IRQ,
}, {
.name = "hold 4s",
.start = PWRON_D4SR_INT,
.end = PWRON_D4SR_INT,
.flags = IORESOURCE_IRQ,
},
};
static const struct mfd_cell hi655x_pmic_devs[] = {
{
.name = "hi65xx-powerkey",
.num_resources = ARRAY_SIZE(pwrkey_resources),
.resources = &pwrkey_resources[0],
},
{ .name = "hi655x-regulator", },
};
static void hi655x_local_irq_clear(struct regmap *map) static void hi655x_local_irq_clear(struct regmap *map)
{ {
int i; int i;
...@@ -80,12 +105,9 @@ static int hi655x_pmic_probe(struct platform_device *pdev) ...@@ -80,12 +105,9 @@ static int hi655x_pmic_probe(struct platform_device *pdev)
pmic->dev = dev; pmic->dev = dev;
pmic->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pmic->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!pmic->res)
return -ENOENT;
base = devm_ioremap_resource(dev, pmic->res); base = devm_ioremap_resource(dev, pmic->res);
if (!base) if (IS_ERR(base))
return -ENOMEM; return PTR_ERR(base);
pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base, pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
&hi655x_regmap_config); &hi655x_regmap_config);
...@@ -123,7 +145,8 @@ static int hi655x_pmic_probe(struct platform_device *pdev) ...@@ -123,7 +145,8 @@ static int hi655x_pmic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pmic); platform_set_drvdata(pdev, pmic);
ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, hi655x_pmic_devs, ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, hi655x_pmic_devs,
ARRAY_SIZE(hi655x_pmic_devs), NULL, 0, NULL); ARRAY_SIZE(hi655x_pmic_devs), NULL, 0,
regmap_irq_get_domain(pmic->irq_data));
if (ret) { if (ret) {
dev_err(dev, "Failed to register device %d\n", ret); dev_err(dev, "Failed to register device %d\n", ret);
regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data); regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data);
......
...@@ -623,6 +623,14 @@ static struct dmi_system_id kempld_dmi_table[] __initdata = { ...@@ -623,6 +623,14 @@ static struct dmi_system_id kempld_dmi_table[] __initdata = {
}, },
.driver_data = (void *)&kempld_platform_data_generic, .driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device, .callback = kempld_create_platform_device,
}, {
.ident = "CSL6",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
DMI_MATCH(DMI_BOARD_NAME, "COMe-cSL6"),
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, { }, {
.ident = "CVV6", .ident = "CVV6",
.matches = { .matches = {
...@@ -646,6 +654,14 @@ static struct dmi_system_id kempld_dmi_table[] __initdata = { ...@@ -646,6 +654,14 @@ static struct dmi_system_id kempld_dmi_table[] __initdata = {
}, },
.driver_data = (void *)&kempld_platform_data_generic, .driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device, .callback = kempld_create_platform_device,
}, {
.ident = "MAL1",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
DMI_MATCH(DMI_BOARD_NAME, "COMe-mAL10"),
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, { }, {
.ident = "MBR1", .ident = "MBR1",
.matches = { .matches = {
......
...@@ -561,7 +561,7 @@ static int __init max14577_i2c_init(void) ...@@ -561,7 +561,7 @@ static int __init max14577_i2c_init(void)
return i2c_add_driver(&max14577_i2c_driver); return i2c_add_driver(&max14577_i2c_driver);
} }
subsys_initcall(max14577_i2c_init); module_init(max14577_i2c_init);
static void __exit max14577_i2c_exit(void) static void __exit max14577_i2c_exit(void)
{ {
......
...@@ -31,25 +31,25 @@ ...@@ -31,25 +31,25 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/max77620.h> #include <linux/mfd/max77620.h>
#include <linux/module.h> #include <linux/init.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/slab.h> #include <linux/slab.h>
static struct resource gpio_resources[] = { static const struct resource gpio_resources[] = {
DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO), DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO),
}; };
static struct resource power_resources[] = { static const struct resource power_resources[] = {
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_MBATLOW), DEFINE_RES_IRQ(MAX77620_IRQ_LBT_MBATLOW),
}; };
static struct resource rtc_resources[] = { static const struct resource rtc_resources[] = {
DEFINE_RES_IRQ(MAX77620_IRQ_TOP_RTC), DEFINE_RES_IRQ(MAX77620_IRQ_TOP_RTC),
}; };
static struct resource thermal_resources[] = { static const struct resource thermal_resources[] = {
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM1), DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM1),
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM2), DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM2),
}; };
...@@ -111,15 +111,6 @@ static const struct mfd_cell max20024_children[] = { ...@@ -111,15 +111,6 @@ static const struct mfd_cell max20024_children[] = {
}, },
}; };
static struct regmap_irq_chip max77620_top_irq_chip = {
.name = "max77620-top",
.irqs = max77620_top_irqs,
.num_irqs = ARRAY_SIZE(max77620_top_irqs),
.num_regs = 2,
.status_base = MAX77620_REG_IRQTOP,
.mask_base = MAX77620_REG_IRQTOPM,
};
static const struct regmap_range max77620_readable_ranges[] = { static const struct regmap_range max77620_readable_ranges[] = {
regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4), regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
}; };
...@@ -180,6 +171,51 @@ static const struct regmap_config max20024_regmap_config = { ...@@ -180,6 +171,51 @@ static const struct regmap_config max20024_regmap_config = {
.volatile_table = &max77620_volatile_table, .volatile_table = &max77620_volatile_table,
}; };
/*
* MAX77620 and MAX20024 has the following steps of the interrupt handling
* for TOP interrupts:
* 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM.
* 2. Read IRQTOP and service the interrupt.
* 3. Once all interrupts has been checked and serviced, the interrupt service
* routine un-masks the hardware interrupt line by clearing GLBLM.
*/
static int max77620_irq_global_mask(void *irq_drv_data)
{
struct max77620_chip *chip = irq_drv_data;
int ret;
ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
MAX77620_GLBLM_MASK, MAX77620_GLBLM_MASK);
if (ret < 0)
dev_err(chip->dev, "Failed to set GLBLM: %d\n", ret);
return ret;
}
static int max77620_irq_global_unmask(void *irq_drv_data)
{
struct max77620_chip *chip = irq_drv_data;
int ret;
ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
MAX77620_GLBLM_MASK, 0);
if (ret < 0)
dev_err(chip->dev, "Failed to reset GLBLM: %d\n", ret);
return ret;
}
static struct regmap_irq_chip max77620_top_irq_chip = {
.name = "max77620-top",
.irqs = max77620_top_irqs,
.num_irqs = ARRAY_SIZE(max77620_top_irqs),
.num_regs = 2,
.status_base = MAX77620_REG_IRQTOP,
.mask_base = MAX77620_REG_IRQTOPM,
.handle_pre_irq = max77620_irq_global_mask,
.handle_post_irq = max77620_irq_global_unmask,
};
/* max77620_get_fps_period_reg_value: Get FPS bit field value from /* max77620_get_fps_period_reg_value: Get FPS bit field value from
* requested periods. * requested periods.
* MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560 * MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560
...@@ -433,6 +469,7 @@ static int max77620_probe(struct i2c_client *client, ...@@ -433,6 +469,7 @@ static int max77620_probe(struct i2c_client *client,
if (ret < 0) if (ret < 0)
return ret; return ret;
max77620_top_irq_chip.irq_drv_data = chip;
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq, ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
IRQF_ONESHOT | IRQF_SHARED, IRQF_ONESHOT | IRQF_SHARED,
chip->irq_base, &max77620_top_irq_chip, chip->irq_base, &max77620_top_irq_chip,
...@@ -568,7 +605,6 @@ static const struct i2c_device_id max77620_id[] = { ...@@ -568,7 +605,6 @@ static const struct i2c_device_id max77620_id[] = {
{"max20024", MAX20024}, {"max20024", MAX20024},
{}, {},
}; };
MODULE_DEVICE_TABLE(i2c, max77620_id);
static const struct dev_pm_ops max77620_pm_ops = { static const struct dev_pm_ops max77620_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume) SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume)
...@@ -582,11 +618,4 @@ static struct i2c_driver max77620_driver = { ...@@ -582,11 +618,4 @@ static struct i2c_driver max77620_driver = {
.probe = max77620_probe, .probe = max77620_probe,
.id_table = max77620_id, .id_table = max77620_id,
}; };
builtin_i2c_driver(max77620_driver);
module_i2c_driver(max77620_driver);
MODULE_DESCRIPTION("MAX77620/MAX20024 Multi Function Device Core Driver");
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
MODULE_AUTHOR("Chaitanya Bandi <bandik@nvidia.com>");
MODULE_AUTHOR("Mallikarjun Kasoju <mkasoju@nvidia.com>");
MODULE_LICENSE("GPL v2");
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h> #include <linux/init.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/max77693-common.h> #include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77843-private.h> #include <linux/mfd/max77843-private.h>
...@@ -171,19 +171,6 @@ static int max77843_probe(struct i2c_client *i2c, ...@@ -171,19 +171,6 @@ static int max77843_probe(struct i2c_client *i2c,
return ret; return ret;
} }
static int max77843_remove(struct i2c_client *i2c)
{
struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
mfd_remove_devices(max77843->dev);
regmap_del_irq_chip(max77843->irq, max77843->irq_data_topsys);
i2c_unregister_device(max77843->i2c_chg);
return 0;
}
static const struct of_device_id max77843_dt_match[] = { static const struct of_device_id max77843_dt_match[] = {
{ .compatible = "maxim,max77843", }, { .compatible = "maxim,max77843", },
{ }, { },
...@@ -193,7 +180,6 @@ static const struct i2c_device_id max77843_id[] = { ...@@ -193,7 +180,6 @@ static const struct i2c_device_id max77843_id[] = {
{ "max77843", TYPE_MAX77843, }, { "max77843", TYPE_MAX77843, },
{ }, { },
}; };
MODULE_DEVICE_TABLE(i2c, max77843_id);
static int __maybe_unused max77843_suspend(struct device *dev) static int __maybe_unused max77843_suspend(struct device *dev)
{ {
...@@ -226,9 +212,9 @@ static struct i2c_driver max77843_i2c_driver = { ...@@ -226,9 +212,9 @@ static struct i2c_driver max77843_i2c_driver = {
.name = "max77843", .name = "max77843",
.pm = &max77843_pm, .pm = &max77843_pm,
.of_match_table = max77843_dt_match, .of_match_table = max77843_dt_match,
.suppress_bind_attrs = true,
}, },
.probe = max77843_probe, .probe = max77843_probe,
.remove = max77843_remove,
.id_table = max77843_id, .id_table = max77843_id,
}; };
...@@ -237,9 +223,3 @@ static int __init max77843_i2c_init(void) ...@@ -237,9 +223,3 @@ static int __init max77843_i2c_init(void)
return i2c_add_driver(&max77843_i2c_driver); return i2c_add_driver(&max77843_i2c_driver);
} }
subsys_initcall(max77843_i2c_init); subsys_initcall(max77843_i2c_init);
static void __exit max77843_i2c_exit(void)
{
i2c_del_driver(&max77843_i2c_driver);
}
module_exit(max77843_i2c_exit);
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/mfd/max8925.h> #include <linux/mfd/max8925.h>
...@@ -133,7 +133,6 @@ static const struct i2c_device_id max8925_id_table[] = { ...@@ -133,7 +133,6 @@ static const struct i2c_device_id max8925_id_table[] = {
{ "max8925", 0 }, { "max8925", 0 },
{ }, { },
}; };
MODULE_DEVICE_TABLE(i2c, max8925_id_table);
static int max8925_dt_init(struct device_node *np, struct device *dev, static int max8925_dt_init(struct device_node *np, struct device *dev,
struct max8925_platform_data *pdata) struct max8925_platform_data *pdata)
...@@ -240,7 +239,6 @@ static const struct of_device_id max8925_dt_ids[] = { ...@@ -240,7 +239,6 @@ static const struct of_device_id max8925_dt_ids[] = {
{ .compatible = "maxim,max8925", }, { .compatible = "maxim,max8925", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, max8925_dt_ids);
static struct i2c_driver max8925_driver = { static struct i2c_driver max8925_driver = {
.driver = { .driver = {
...@@ -264,13 +262,3 @@ static int __init max8925_i2c_init(void) ...@@ -264,13 +262,3 @@ static int __init max8925_i2c_init(void)
return ret; return ret;
} }
subsys_initcall(max8925_i2c_init); subsys_initcall(max8925_i2c_init);
static void __exit max8925_i2c_exit(void)
{
i2c_del_driver(&max8925_driver);
}
module_exit(max8925_i2c_exit);
MODULE_DESCRIPTION("I2C Driver for Maxim 8925");
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_LICENSE("GPL");
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* max8997.c - mfd core driver for the Maxim 8966 and 8997 * max8997.c - mfd core driver for the Maxim 8966 and 8997
* *
* Copyright (C) 2011 Samsung Electronics * Copyright (C) 2011 Samsung Electronics
* MyungJoo Ham <myungjoo.ham@smasung.com> * MyungJoo Ham <myungjoo.ham@samsung.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/module.h> #include <linux/init.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/max8997.h> #include <linux/mfd/max8997.h>
...@@ -55,7 +55,6 @@ static const struct of_device_id max8997_pmic_dt_match[] = { ...@@ -55,7 +55,6 @@ static const struct of_device_id max8997_pmic_dt_match[] = {
{ .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 }, { .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, max8997_pmic_dt_match);
#endif #endif
int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
...@@ -263,24 +262,11 @@ static int max8997_i2c_probe(struct i2c_client *i2c, ...@@ -263,24 +262,11 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
return ret; return ret;
} }
static int max8997_i2c_remove(struct i2c_client *i2c)
{
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
mfd_remove_devices(max8997->dev);
i2c_unregister_device(max8997->muic);
i2c_unregister_device(max8997->haptic);
i2c_unregister_device(max8997->rtc);
return 0;
}
static const struct i2c_device_id max8997_i2c_id[] = { static const struct i2c_device_id max8997_i2c_id[] = {
{ "max8997", TYPE_MAX8997 }, { "max8997", TYPE_MAX8997 },
{ "max8966", TYPE_MAX8966 }, { "max8966", TYPE_MAX8966 },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
static u8 max8997_dumpaddr_pmic[] = { static u8 max8997_dumpaddr_pmic[] = {
MAX8997_REG_INT1MSK, MAX8997_REG_INT1MSK,
...@@ -510,10 +496,10 @@ static struct i2c_driver max8997_i2c_driver = { ...@@ -510,10 +496,10 @@ static struct i2c_driver max8997_i2c_driver = {
.driver = { .driver = {
.name = "max8997", .name = "max8997",
.pm = &max8997_pm, .pm = &max8997_pm,
.suppress_bind_attrs = true,
.of_match_table = of_match_ptr(max8997_pmic_dt_match), .of_match_table = of_match_ptr(max8997_pmic_dt_match),
}, },
.probe = max8997_i2c_probe, .probe = max8997_i2c_probe,
.remove = max8997_i2c_remove,
.id_table = max8997_i2c_id, .id_table = max8997_i2c_id,
}; };
...@@ -523,13 +509,3 @@ static int __init max8997_i2c_init(void) ...@@ -523,13 +509,3 @@ static int __init max8997_i2c_init(void)
} }
/* init early so consumer devices can complete system boot */ /* init early so consumer devices can complete system boot */
subsys_initcall(max8997_i2c_init); subsys_initcall(max8997_i2c_init);
static void __exit max8997_i2c_exit(void)
{
i2c_del_driver(&max8997_i2c_driver);
}
module_exit(max8997_i2c_exit);
MODULE_DESCRIPTION("MAXIM 8997 multi-function core driver");
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
MODULE_LICENSE("GPL");
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
*/ */
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -138,7 +136,6 @@ static const struct of_device_id max8998_dt_match[] = { ...@@ -138,7 +136,6 @@ static const struct of_device_id max8998_dt_match[] = {
{ .compatible = "ti,lp3974", .data = (void *)TYPE_LP3974 }, { .compatible = "ti,lp3974", .data = (void *)TYPE_LP3974 },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, max8998_dt_match);
#endif #endif
/* /*
...@@ -254,23 +251,11 @@ static int max8998_i2c_probe(struct i2c_client *i2c, ...@@ -254,23 +251,11 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
return ret; return ret;
} }
static int max8998_i2c_remove(struct i2c_client *i2c)
{
struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
mfd_remove_devices(max8998->dev);
max8998_irq_exit(max8998);
i2c_unregister_device(max8998->rtc);
return 0;
}
static const struct i2c_device_id max8998_i2c_id[] = { static const struct i2c_device_id max8998_i2c_id[] = {
{ "max8998", TYPE_MAX8998 }, { "max8998", TYPE_MAX8998 },
{ "lp3974", TYPE_LP3974}, { "lp3974", TYPE_LP3974},
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
static int max8998_suspend(struct device *dev) static int max8998_suspend(struct device *dev)
{ {
...@@ -378,10 +363,10 @@ static struct i2c_driver max8998_i2c_driver = { ...@@ -378,10 +363,10 @@ static struct i2c_driver max8998_i2c_driver = {
.driver = { .driver = {
.name = "max8998", .name = "max8998",
.pm = &max8998_pm, .pm = &max8998_pm,
.suppress_bind_attrs = true,
.of_match_table = of_match_ptr(max8998_dt_match), .of_match_table = of_match_ptr(max8998_dt_match),
}, },
.probe = max8998_i2c_probe, .probe = max8998_i2c_probe,
.remove = max8998_i2c_remove,
.id_table = max8998_i2c_id, .id_table = max8998_i2c_id,
}; };
...@@ -391,13 +376,3 @@ static int __init max8998_i2c_init(void) ...@@ -391,13 +376,3 @@ static int __init max8998_i2c_init(void)
} }
/* init early so consumer devices can complete system boot */ /* init early so consumer devices can complete system boot */
subsys_initcall(max8998_i2c_init); subsys_initcall(max8998_i2c_init);
static void __exit max8998_i2c_exit(void)
{
i2c_del_driver(&max8998_i2c_driver);
}
module_exit(max8998_i2c_exit);
MODULE_DESCRIPTION("MAXIM 8998 multi-function core driver");
MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
MODULE_LICENSE("GPL");
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <linux/platform_data/usb-omap.h> #include <linux/platform_data/usb-omap.h>
#include <linux/of.h> #include <linux/of.h>
#include "omap-usb.h"
#define USBTLL_DRIVER_NAME "usbhs_tll" #define USBTLL_DRIVER_NAME "usbhs_tll"
/* TLL Register Set */ /* TLL Register Set */
......
...@@ -34,7 +34,13 @@ struct qcom_rpm_resource { ...@@ -34,7 +34,13 @@ struct qcom_rpm_resource {
struct qcom_rpm_data { struct qcom_rpm_data {
u32 version; u32 version;
const struct qcom_rpm_resource *resource_table; const struct qcom_rpm_resource *resource_table;
unsigned n_resources; unsigned int n_resources;
unsigned int req_ctx_off;
unsigned int req_sel_off;
unsigned int ack_ctx_off;
unsigned int ack_sel_off;
unsigned int req_sel_size;
unsigned int ack_sel_size;
}; };
struct qcom_rpm { struct qcom_rpm {
...@@ -61,17 +67,11 @@ struct qcom_rpm { ...@@ -61,17 +67,11 @@ struct qcom_rpm {
#define RPM_REQUEST_TIMEOUT (5 * HZ) #define RPM_REQUEST_TIMEOUT (5 * HZ)
#define RPM_REQUEST_CONTEXT 3 #define RPM_MAX_SEL_SIZE 7
#define RPM_REQ_SELECT 11
#define RPM_ACK_CONTEXT 15
#define RPM_ACK_SELECTOR 23
#define RPM_SELECT_SIZE 7
#define RPM_NOTIFICATION BIT(30) #define RPM_NOTIFICATION BIT(30)
#define RPM_REJECTED BIT(31) #define RPM_REJECTED BIT(31)
#define RPM_SIGNAL BIT(2)
static const struct qcom_rpm_resource apq8064_rpm_resource_table[] = { static const struct qcom_rpm_resource apq8064_rpm_resource_table[] = {
[QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 }, [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 },
[QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 }, [QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 },
...@@ -157,6 +157,12 @@ static const struct qcom_rpm_data apq8064_template = { ...@@ -157,6 +157,12 @@ static const struct qcom_rpm_data apq8064_template = {
.version = 3, .version = 3,
.resource_table = apq8064_rpm_resource_table, .resource_table = apq8064_rpm_resource_table,
.n_resources = ARRAY_SIZE(apq8064_rpm_resource_table), .n_resources = ARRAY_SIZE(apq8064_rpm_resource_table),
.req_ctx_off = 3,
.req_sel_off = 11,
.ack_ctx_off = 15,
.ack_sel_off = 23,
.req_sel_size = 4,
.ack_sel_size = 7,
}; };
static const struct qcom_rpm_resource msm8660_rpm_resource_table[] = { static const struct qcom_rpm_resource msm8660_rpm_resource_table[] = {
...@@ -240,6 +246,12 @@ static const struct qcom_rpm_data msm8660_template = { ...@@ -240,6 +246,12 @@ static const struct qcom_rpm_data msm8660_template = {
.version = 2, .version = 2,
.resource_table = msm8660_rpm_resource_table, .resource_table = msm8660_rpm_resource_table,
.n_resources = ARRAY_SIZE(msm8660_rpm_resource_table), .n_resources = ARRAY_SIZE(msm8660_rpm_resource_table),
.req_ctx_off = 3,
.req_sel_off = 11,
.ack_ctx_off = 19,
.ack_sel_off = 27,
.req_sel_size = 7,
.ack_sel_size = 7,
}; };
static const struct qcom_rpm_resource msm8960_rpm_resource_table[] = { static const struct qcom_rpm_resource msm8960_rpm_resource_table[] = {
...@@ -322,6 +334,12 @@ static const struct qcom_rpm_data msm8960_template = { ...@@ -322,6 +334,12 @@ static const struct qcom_rpm_data msm8960_template = {
.version = 3, .version = 3,
.resource_table = msm8960_rpm_resource_table, .resource_table = msm8960_rpm_resource_table,
.n_resources = ARRAY_SIZE(msm8960_rpm_resource_table), .n_resources = ARRAY_SIZE(msm8960_rpm_resource_table),
.req_ctx_off = 3,
.req_sel_off = 11,
.ack_ctx_off = 15,
.ack_sel_off = 23,
.req_sel_size = 4,
.ack_sel_size = 7,
}; };
static const struct qcom_rpm_resource ipq806x_rpm_resource_table[] = { static const struct qcom_rpm_resource ipq806x_rpm_resource_table[] = {
...@@ -362,6 +380,12 @@ static const struct qcom_rpm_data ipq806x_template = { ...@@ -362,6 +380,12 @@ static const struct qcom_rpm_data ipq806x_template = {
.version = 3, .version = 3,
.resource_table = ipq806x_rpm_resource_table, .resource_table = ipq806x_rpm_resource_table,
.n_resources = ARRAY_SIZE(ipq806x_rpm_resource_table), .n_resources = ARRAY_SIZE(ipq806x_rpm_resource_table),
.req_ctx_off = 3,
.req_sel_off = 11,
.ack_ctx_off = 15,
.ack_sel_off = 23,
.req_sel_size = 4,
.ack_sel_size = 7,
}; };
static const struct of_device_id qcom_rpm_of_match[] = { static const struct of_device_id qcom_rpm_of_match[] = {
...@@ -380,7 +404,7 @@ int qcom_rpm_write(struct qcom_rpm *rpm, ...@@ -380,7 +404,7 @@ int qcom_rpm_write(struct qcom_rpm *rpm,
{ {
const struct qcom_rpm_resource *res; const struct qcom_rpm_resource *res;
const struct qcom_rpm_data *data = rpm->data; const struct qcom_rpm_data *data = rpm->data;
u32 sel_mask[RPM_SELECT_SIZE] = { 0 }; u32 sel_mask[RPM_MAX_SEL_SIZE] = { 0 };
int left; int left;
int ret = 0; int ret = 0;
int i; int i;
...@@ -398,12 +422,12 @@ int qcom_rpm_write(struct qcom_rpm *rpm, ...@@ -398,12 +422,12 @@ int qcom_rpm_write(struct qcom_rpm *rpm,
writel_relaxed(buf[i], RPM_REQ_REG(rpm, res->target_id + i)); writel_relaxed(buf[i], RPM_REQ_REG(rpm, res->target_id + i));
bitmap_set((unsigned long *)sel_mask, res->select_id, 1); bitmap_set((unsigned long *)sel_mask, res->select_id, 1);
for (i = 0; i < ARRAY_SIZE(sel_mask); i++) { for (i = 0; i < rpm->data->req_sel_size; i++) {
writel_relaxed(sel_mask[i], writel_relaxed(sel_mask[i],
RPM_CTRL_REG(rpm, RPM_REQ_SELECT + i)); RPM_CTRL_REG(rpm, rpm->data->req_sel_off + i));
} }
writel_relaxed(BIT(state), RPM_CTRL_REG(rpm, RPM_REQUEST_CONTEXT)); writel_relaxed(BIT(state), RPM_CTRL_REG(rpm, rpm->data->req_ctx_off));
reinit_completion(&rpm->ack); reinit_completion(&rpm->ack);
regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit)); regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit));
...@@ -426,10 +450,11 @@ static irqreturn_t qcom_rpm_ack_interrupt(int irq, void *dev) ...@@ -426,10 +450,11 @@ static irqreturn_t qcom_rpm_ack_interrupt(int irq, void *dev)
u32 ack; u32 ack;
int i; int i;
ack = readl_relaxed(RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT)); ack = readl_relaxed(RPM_CTRL_REG(rpm, rpm->data->ack_ctx_off));
for (i = 0; i < RPM_SELECT_SIZE; i++) for (i = 0; i < rpm->data->ack_sel_size; i++)
writel_relaxed(0, RPM_CTRL_REG(rpm, RPM_ACK_SELECTOR + i)); writel_relaxed(0,
writel(0, RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT)); RPM_CTRL_REG(rpm, rpm->data->ack_sel_off + i));
writel(0, RPM_CTRL_REG(rpm, rpm->data->ack_ctx_off));
if (ack & RPM_NOTIFICATION) { if (ack & RPM_NOTIFICATION) {
dev_warn(rpm->dev, "ignoring notification!\n"); dev_warn(rpm->dev, "ignoring notification!\n");
......
...@@ -600,7 +600,7 @@ static int si476x_core_fwver_to_revision(struct si476x_core *core, ...@@ -600,7 +600,7 @@ static int si476x_core_fwver_to_revision(struct si476x_core *core,
unknown_revision: unknown_revision:
dev_err(&core->client->dev, dev_err(&core->client->dev,
"Unsupported version of the firmware: %d.%d.%d, " "Unsupported version of the firmware: %d.%d.%d, "
"reverting to A10 comptible functions\n", "reverting to A10 compatible functions\n",
major, minor1, minor2); major, minor1, minor2);
return SI476X_REVISION_A10; return SI476X_REVISION_A10;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment