1
0
Fork 0

- New Drivers

- Add support for Merrifield Basin Cove PMIC
 
  - New Device Support
    - Add support for Intel Tiger Lake to Intel LPSS PCI
    - Add support for Intel Sky Lake to Intel LPSS PCI
    - Add support for ST-Ericsson DB8520 to DB8500 PRCMU
 
  - New Functionality
    - Add RTC and PWRC support to MT6323
 
  - Fix-ups
    - Clean-up include files; davinci_voicecodec, asic3, sm501, mt6397
    - Ignore return values from debugfs_create*(); ab3100-*, ab8500-debugfs, aat2870-core
    - Device Tree changes; rn5t618, mt6397
    - Use new I2C API; tps80031, 88pm860x-core, ab3100-core, bcm590xx,
                       da9150-core, max14577, max77693, max77843, max8907,
                       max8925-i2c, max8997, max8998, palmas, twl-core,
    - Remove obsolete code; da9063, jz4740-adc
    - Simplify semantics; timberdale, htc-i2cpld
    - Add 'fall-through' tags; omap-usb-host, db8500-prcmu
    - Remove superfluous prints; ab8500-debugfs, db8500-prcmu, fsl-imx25-tsadc,
                                 intel_soc_pmic_bxtwc, qcom_rpm, sm501
    - Trivial rename/whitespace/typo fixes; mt6397-core, MAINTAINERS
    - Reorganise code structure; mt6397-*
    - Improve code consistency; intel-lpss
    - Use MODULE_SOFTDEP() helper; intel-lpss
    - Use DEFINE_RES_*() helpers; mt6397-core
 
  - Bug Fixes
    - Clean-up resources; max77620
    - Prevent input events being dropped on resume; intel-lpss-pci
    - Prevent sleeping in IRQ context; ezx-pcap
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAl2JUDEACgkQUa+KL4f8
 d2HKPQ//TLMO2Ed7AdhajgpYQVRQ2wM5VGOQLaTj/sO0WTjk3DfPdmp13ZZh9UTN
 evfYiVJI2ofpcliK6Tg8X27oaNg/YK+ff562lyFzMNIQMJ7hpzjvyaAfGhMz4y7I
 tN8RgMNHSU5luywJvJ43OH6K5C+ckg+kPp4Ywvnh3Hwqm3y7QJ9/CshTON69BOCf
 kYvE9dvAqubbTl80aMOqNbl/p6+h/C9sFhvGsC7LnWdE9vev/SE1kYmjm1ha5Z1N
 hRbnAw1nXidV1mB6oIhzvsx3MgpvBjvi6UXg8TCWuZTUlwMplgAfsDKWb6J9czxB
 lhP0W5/wuJPIkdZPRSEGVJ6MCsxpF5GcGknWTf1dL2hsx0kh1JsT/AUQeHR02NpQ
 pnGF7YDgQugHnkHqr+JfbswlIunh5U3ZxspvHQWTxzaVQvQ0eGk91Kqr5zKhdHf9
 z5e1j/VtjzAsYqGkamAjXCXPES1PIvwqKT6qLrERAoFBgigwP/i4nxSlTJGvqTVY
 M3+RH7I7IWfGCuJ227PWpkvFgzX7N+okKxujOWo+Fd4DH6lhMDstnrIoVZxpEfE+
 cQLo5soG7mJtk9meGFTrxkfT3IqcVWMG0vCXeaureNS1N+OjtZLRDN7ZuG2d8zFx
 nRCi+tJoAZe34DenfiSe+VcczlOOtqR2JpZKAdwW3ZT3Kcfl9U4=
 =03Zw
 -----END PGP SIGNATURE-----

Merge tag 'mfd-next-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "New Drivers:
   - Add support for Merrifield Basin Cove PMIC

  New Device Support:
   - Add support for Intel Tiger Lake to Intel LPSS PCI
   - Add support for Intel Sky Lake to Intel LPSS PCI
   - Add support for ST-Ericsson DB8520 to DB8500 PRCMU

  New Functionality:
   - Add RTC and PWRC support to MT6323

  Fix-ups:
   - Clean-up include files; davinci_voicecodec, asic3, sm501, mt6397
   - Ignore return values from debugfs_create*(); ab3100-*, ab8500-debugfs, aat2870-core
   - Device Tree changes; rn5t618, mt6397
   - Use new I2C API; tps80031, 88pm860x-core, ab3100-core, bcm590xx,
                      da9150-core, max14577, max77693, max77843, max8907,
                      max8925-i2c, max8997, max8998, palmas, twl-core,
   - Remove obsolete code; da9063, jz4740-adc
   - Simplify semantics; timberdale, htc-i2cpld
   - Add 'fall-through' tags; omap-usb-host, db8500-prcmu
   - Remove superfluous prints; ab8500-debugfs, db8500-prcmu, fsl-imx25-tsadc,
                                intel_soc_pmic_bxtwc, qcom_rpm, sm501
   - Trivial rename/whitespace/typo fixes; mt6397-core, MAINTAINERS
   - Reorganise code structure; mt6397-*
   - Improve code consistency; intel-lpss
   - Use MODULE_SOFTDEP() helper; intel-lpss
   - Use DEFINE_RES_*() helpers; mt6397-core

  Bug Fixes:
   - Clean-up resources; max77620
   - Prevent input events being dropped on resume; intel-lpss-pci
   - Prevent sleeping in IRQ context; ezx-pcap"

* tag 'mfd-next-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (48 commits)
  mfd: mt6323: Add MT6323 RTC and PWRC
  mfd: mt6323: Replace boilerplate resource code with DEFINE_RES_* macros
  mfd: mt6397: Add mutex include
  dt-bindings: mfd: mediatek: Add MT6323 Power Controller
  dt-bindings: mfd: mediatek: Update RTC to include MT6323
  dt-bindings: mfd: mediatek: mt6397: Change to relative paths
  mfd: db8500-prcmu: Support the higher DB8520 ARMSS
  mfd: intel-lpss: Use MODULE_SOFTDEP() instead of implicit request
  mfd: htc-i2cpld: Drop check because i2c_unregister_device() is NULL safe
  mfd: sm501: Include the GPIO driver header
  mfd: intel-lpss: Add Intel Skylake ACPI IDs
  mfd: intel-lpss: Consistently use GENMASK()
  mfd: Add support for Merrifield Basin Cove PMIC
  mfd: ezx-pcap: Replace mutex_lock with spin_lock
  mfd: asic3: Include the right header
  MAINTAINERS: altera-sysmgr: Fix typo in a filepath
  mfd: mt6397: Extract IRQ related code from core driver
  mfd: mt6397: Rename macros to something more readable
  mfd: Remove dev_err() usage after platform_get_irq()
  mfd: db8500-prcmu: Mark expected switch fall-throughs
  ...
alistair/sunxi64-5.4-dsi
Linus Torvalds 2019-09-23 19:37:49 -07:00
commit 4c07e2ddab
45 changed files with 742 additions and 727 deletions

View File

@ -8,11 +8,12 @@ MT6397/MT6323 is a multifunction device with the following sub modules:
- Clock
- LED
- Keys
- Power controller
It is interfaced to host controller using SPI interface by a proprietary hardware
called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
See the following for pwarp node definitions:
Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
../soc/mediatek/pwrap.txt
This document describes the binding for MFD device and its sub module.
@ -22,14 +23,16 @@ compatible: "mediatek,mt6397" or "mediatek,mt6323"
Optional subnodes:
- rtc
Required properties:
Required properties: Should be one of follows
- compatible: "mediatek,mt6323-rtc"
- compatible: "mediatek,mt6397-rtc"
For details, see ../rtc/rtc-mt6397.txt
- regulators
Required properties:
- compatible: "mediatek,mt6397-regulator"
see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt
see ../regulator/mt6397-regulator.txt
- compatible: "mediatek,mt6323-regulator"
see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
see ../regulator/mt6323-regulator.txt
- codec
Required properties:
- compatible: "mediatek,mt6397-codec"
@ -39,12 +42,17 @@ Optional subnodes:
- led
Required properties:
- compatible: "mediatek,mt6323-led"
see Documentation/devicetree/bindings/leds/leds-mt6323.txt
see ../leds/leds-mt6323.txt
- keys
Required properties:
- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
see Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
see ../input/mtk-pmic-keys.txt
- power-controller
Required properties:
- compatible: "mediatek,mt6323-pwrc"
For details, see ../power/reset/mt6323-poweroff.txt
Example:
pwrap: pwrap@1000f000 {

View File

@ -14,6 +14,10 @@ Required properties:
"ricoh,rc5t619"
- reg: the I2C slave address of the device
Optional properties:
- system-power-controller:
See Documentation/devicetree/bindings/power/power-controller.txt
Sub-nodes:
- regulators: the node is required if the regulator functionality is
needed. The valid regulator names are: DCDC1, DCDC2, DCDC3, DCDC4
@ -28,6 +32,7 @@ Example:
pmic@32 {
compatible = "ricoh,rn5t618";
reg = <0x32>;
system-power-controller;
regulators {
DCDC1 {

View File

@ -0,0 +1,20 @@
Device Tree Bindings for Power Controller on MediaTek PMIC
The power controller which could be found on PMIC is responsible for externally
powering off or on the remote MediaTek SoC through the circuit BBPU.
Required properties:
- compatible: Should be one of follows
"mediatek,mt6323-pwrc": for MT6323 PMIC
Example:
pmic {
compatible = "mediatek,mt6323";
...
power-controller {
compatible = "mediatek,mt6323-pwrc";
};
}

View File

@ -728,7 +728,7 @@ ALTERA SYSTEM MANAGER DRIVER
M: Thor Thayer <thor.thayer@linux.intel.com>
S: Maintained
F: drivers/mfd/altera-sysmgr.c
F: include/linux/mfd/altera-sysgmr.h
F: include/linux/mfd/altera-sysmgr.h
ALTERA SYSTEM RESOURCE DRIVER FOR ARRIA10 DEVKIT
M: Thor Thayer <thor.thayer@linux.intel.com>

View File

@ -425,10 +425,10 @@ static int pm800_pages_init(struct pm80x_chip *chip)
return -ENODEV;
/* PM800 block power page */
subchip->power_page = i2c_new_dummy(client->adapter,
subchip->power_page = i2c_new_dummy_device(client->adapter,
subchip->power_page_addr);
if (subchip->power_page == NULL) {
ret = -ENODEV;
if (IS_ERR(subchip->power_page)) {
ret = PTR_ERR(subchip->power_page);
goto out;
}
@ -444,10 +444,10 @@ static int pm800_pages_init(struct pm80x_chip *chip)
i2c_set_clientdata(subchip->power_page, chip);
/* PM800 block GPADC */
subchip->gpadc_page = i2c_new_dummy(client->adapter,
subchip->gpadc_page = i2c_new_dummy_device(client->adapter,
subchip->gpadc_page_addr);
if (subchip->gpadc_page == NULL) {
ret = -ENODEV;
if (IS_ERR(subchip->gpadc_page)) {
ret = PTR_ERR(subchip->gpadc_page);
goto out;
}

View File

@ -1178,12 +1178,12 @@ static int pm860x_probe(struct i2c_client *client)
*/
if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
chip->companion_addr = pdata->companion_addr;
chip->companion = i2c_new_dummy(chip->client->adapter,
chip->companion = i2c_new_dummy_device(chip->client->adapter,
chip->companion_addr);
if (!chip->companion) {
if (IS_ERR(chip->companion)) {
dev_err(&client->dev,
"Failed to allocate I2C companion device\n");
return -ENODEV;
return PTR_ERR(chip->companion);
}
chip->regmap_companion = regmap_init_i2c(chip->companion,
&pm860x_regmap_config);

View File

@ -589,6 +589,17 @@ config INTEL_SOC_PMIC_CHTDC_TI
Select this option for supporting Dollar Cove (TI version) PMIC
device that is found on some Intel Cherry Trail systems.
config INTEL_SOC_PMIC_MRFLD
tristate "Support for Intel Merrifield Basin Cove PMIC"
depends on GPIOLIB
depends on ACPI
depends on INTEL_SCU_IPC
select MFD_CORE
select REGMAP_IRQ
help
Select this option for supporting Basin Cove PMIC device
that is found on Intel Merrifield systems.
config MFD_INTEL_LPSS
tristate
select COMMON_CLK
@ -641,15 +652,6 @@ config MFD_JANZ_CMODIO
host many different types of MODULbus daughterboards, including
CAN and GPIO controllers.
config MFD_JZ4740_ADC
bool "Janz JZ4740 ADC core"
select MFD_CORE
select GENERIC_IRQ_CHIP
depends on MACH_JZ4740
help
Say yes here if you want support for the ADC unit in the JZ4740 SoC.
This driver is necessary for jz4740-battery and jz4740-hwmon driver.
config MFD_KEMPLD
tristate "Kontron module PLD device"
select MFD_CORE

View File

@ -189,7 +189,6 @@ obj-$(CONFIG_LPC_SCH) += lpc_sch.o
obj-$(CONFIG_LPC_ICH) += lpc_ich.o
obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o
obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o
obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
obj-$(CONFIG_MFD_VX855) += vx855.o
obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
@ -239,7 +238,9 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
mt6397-objs := mt6397-core.o mt6397-irq.o
obj-$(CONFIG_MFD_MT6397) += mt6397.o
obj-$(CONFIG_INTEL_SOC_PMIC_MRFLD) += intel_soc_pmic_mrfld.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o

View File

@ -865,10 +865,10 @@ static int ab3100_probe(struct i2c_client *client,
&ab3100->chip_name[0]);
/* Attach a second dummy i2c_client to the test register address */
ab3100->testreg_client = i2c_new_dummy(client->adapter,
ab3100->testreg_client = i2c_new_dummy_device(client->adapter,
client->addr + 1);
if (!ab3100->testreg_client) {
err = -ENOMEM;
if (IS_ERR(ab3100->testreg_client)) {
err = PTR_ERR(ab3100->testreg_client);
goto exit_no_testreg_client;
}

View File

@ -2680,16 +2680,12 @@ static int ab8500_debug_probe(struct platform_device *plf)
irq_ab8500 = res->start;
irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
if (irq_first < 0) {
dev_err(&plf->dev, "First irq not found, err %d\n", irq_first);
if (irq_first < 0)
return irq_first;
}
irq_last = platform_get_irq_byname(plf, "IRQ_LAST");
if (irq_last < 0) {
dev_err(&plf->dev, "Last irq not found, err %d\n", irq_last);
if (irq_last < 0)
return irq_last;
}
ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);

View File

@ -15,7 +15,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/slab.h>

View File

@ -61,11 +61,11 @@ static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri,
}
/* Secondary I2C slave address is the base address with A(2) asserted */
bcm590xx->i2c_sec = i2c_new_dummy(i2c_pri->adapter,
bcm590xx->i2c_sec = i2c_new_dummy_device(i2c_pri->adapter,
i2c_pri->addr | BIT(2));
if (!bcm590xx->i2c_sec) {
if (IS_ERR(bcm590xx->i2c_sec)) {
dev_err(&i2c_pri->dev, "failed to add secondary I2C device\n");
return -ENODEV;
return PTR_ERR(bcm590xx->i2c_sec);
}
i2c_set_clientdata(bcm590xx->i2c_sec, bcm590xx);

View File

@ -420,10 +420,10 @@ static int da9150_probe(struct i2c_client *client,
qif_addr = da9150_reg_read(da9150, DA9150_CORE2WIRE_CTRL_A);
qif_addr = (qif_addr & DA9150_CORE_BASE_ADDR_MASK) >> 1;
qif_addr |= DA9150_QIF_I2C_ADDR_LSB;
da9150->core_qif = i2c_new_dummy(client->adapter, qif_addr);
if (!da9150->core_qif) {
da9150->core_qif = i2c_new_dummy_device(client->adapter, qif_addr);
if (IS_ERR(da9150->core_qif)) {
dev_err(da9150->dev, "Failed to attach QIF client\n");
return -ENODEV;
return PTR_ERR(da9150->core_qif);
}
i2c_set_clientdata(da9150->core_qif, da9150);

View File

@ -19,7 +19,6 @@
#include <sound/pcm.h>
#include <linux/mfd/davinci_voicecodec.h>
#include <mach/hardware.h>
static const struct regmap_config davinci_vc_regmap = {
.reg_bits = 32,
@ -31,6 +30,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
struct davinci_vc *davinci_vc;
struct resource *res;
struct mfd_cell *cell = NULL;
dma_addr_t fifo_base;
int ret;
davinci_vc = devm_kzalloc(&pdev->dev,
@ -48,6 +48,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
fifo_base = (dma_addr_t)res->start;
davinci_vc->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(davinci_vc->base)) {
ret = PTR_ERR(davinci_vc->base);
@ -70,8 +71,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
}
davinci_vc->davinci_vcif.dma_tx_channel = res->start;
davinci_vc->davinci_vcif.dma_tx_addr =
(dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO);
davinci_vc->davinci_vcif.dma_tx_addr = fifo_base + DAVINCI_VC_WFIFO;
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) {
@ -81,8 +81,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
}
davinci_vc->davinci_vcif.dma_rx_channel = res->start;
davinci_vc->davinci_vcif.dma_rx_addr =
(dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO);
davinci_vc->davinci_vcif.dma_rx_addr = fifo_base + DAVINCI_VC_RFIFO;
davinci_vc->dev = &pdev->dev;
davinci_vc->pdev = pdev;

View File

@ -1695,21 +1695,41 @@ static long round_clock_rate(u8 clock, unsigned long rate)
return rounded_rate;
}
static const unsigned long armss_freqs[] = {
static const unsigned long db8500_armss_freqs[] = {
200000000,
400000000,
800000000,
998400000
};
/* The DB8520 has slightly higher ARMSS max frequency */
static const unsigned long db8520_armss_freqs[] = {
200000000,
400000000,
800000000,
1152000000
};
static long round_armss_rate(unsigned long rate)
{
unsigned long freq = 0;
const unsigned long *freqs;
int nfreqs;
int i;
if (fw_info.version.project == PRCMU_FW_PROJECT_U8520) {
freqs = db8520_armss_freqs;
nfreqs = ARRAY_SIZE(db8520_armss_freqs);
} else {
freqs = db8500_armss_freqs;
nfreqs = ARRAY_SIZE(db8500_armss_freqs);
}
/* Find the corresponding arm opp from the cpufreq table. */
for (i = 0; i < ARRAY_SIZE(armss_freqs); i++) {
freq = armss_freqs[i];
for (i = 0; i < nfreqs; i++) {
freq = freqs[i];
if (rate <= freq)
break;
}
@ -1854,11 +1874,21 @@ static int set_armss_rate(unsigned long rate)
{
unsigned long freq;
u8 opps[] = { ARM_EXTCLK, ARM_50_OPP, ARM_100_OPP, ARM_MAX_OPP };
const unsigned long *freqs;
int nfreqs;
int i;
if (fw_info.version.project == PRCMU_FW_PROJECT_U8520) {
freqs = db8520_armss_freqs;
nfreqs = ARRAY_SIZE(db8520_armss_freqs);
} else {
freqs = db8500_armss_freqs;
nfreqs = ARRAY_SIZE(db8500_armss_freqs);
}
/* Find the corresponding arm opp from the cpufreq table. */
for (i = 0; i < ARRAY_SIZE(armss_freqs); i++) {
freq = armss_freqs[i];
for (i = 0; i < nfreqs; i++) {
freq = freqs[i];
if (rate == freq)
break;
}
@ -3130,10 +3160,8 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(&pdev->dev, "no prcmu irq provided\n");
if (irq <= 0)
return irq;
}
err = request_threaded_irq(irq, prcmu_irq_handler,
prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL);

View File

@ -35,7 +35,7 @@ struct pcap_chip {
/* IO */
u32 buf;
struct mutex io_mutex;
spinlock_t io_lock;
/* IRQ */
unsigned int irq_base;
@ -48,7 +48,7 @@ struct pcap_chip {
struct pcap_adc_request *adc_queue[PCAP_ADC_MAXQ];
u8 adc_head;
u8 adc_tail;
struct mutex adc_mutex;
spinlock_t adc_lock;
};
/* IO */
@ -76,14 +76,15 @@ static int ezx_pcap_putget(struct pcap_chip *pcap, u32 *data)
int ezx_pcap_write(struct pcap_chip *pcap, u8 reg_num, u32 value)
{
unsigned long flags;
int ret;
mutex_lock(&pcap->io_mutex);
spin_lock_irqsave(&pcap->io_lock, flags);
value &= PCAP_REGISTER_VALUE_MASK;
value |= PCAP_REGISTER_WRITE_OP_BIT
| (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
ret = ezx_pcap_putget(pcap, &value);
mutex_unlock(&pcap->io_mutex);
spin_unlock_irqrestore(&pcap->io_lock, flags);
return ret;
}
@ -91,14 +92,15 @@ EXPORT_SYMBOL_GPL(ezx_pcap_write);
int ezx_pcap_read(struct pcap_chip *pcap, u8 reg_num, u32 *value)
{
unsigned long flags;
int ret;
mutex_lock(&pcap->io_mutex);
spin_lock_irqsave(&pcap->io_lock, flags);
*value = PCAP_REGISTER_READ_OP_BIT
| (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
ret = ezx_pcap_putget(pcap, value);
mutex_unlock(&pcap->io_mutex);
spin_unlock_irqrestore(&pcap->io_lock, flags);
return ret;
}
@ -106,11 +108,12 @@ EXPORT_SYMBOL_GPL(ezx_pcap_read);
int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val)
{
unsigned long flags;
int ret;
u32 tmp = PCAP_REGISTER_READ_OP_BIT |
(reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
mutex_lock(&pcap->io_mutex);
spin_lock_irqsave(&pcap->io_lock, flags);
ret = ezx_pcap_putget(pcap, &tmp);
if (ret)
goto out_unlock;
@ -121,7 +124,7 @@ int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val)
ret = ezx_pcap_putget(pcap, &tmp);
out_unlock:
mutex_unlock(&pcap->io_mutex);
spin_unlock_irqrestore(&pcap->io_lock, flags);
return ret;
}
@ -212,14 +215,15 @@ static void pcap_irq_handler(struct irq_desc *desc)
/* ADC */
void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits)
{
unsigned long flags;
u32 tmp;
mutex_lock(&pcap->adc_mutex);
spin_lock_irqsave(&pcap->adc_lock, flags);
ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
mutex_unlock(&pcap->adc_mutex);
spin_unlock_irqrestore(&pcap->adc_lock, flags);
}
EXPORT_SYMBOL_GPL(pcap_set_ts_bits);
@ -234,15 +238,16 @@ static void pcap_disable_adc(struct pcap_chip *pcap)
static void pcap_adc_trigger(struct pcap_chip *pcap)
{
unsigned long flags;
u32 tmp;
u8 head;
mutex_lock(&pcap->adc_mutex);
spin_lock_irqsave(&pcap->adc_lock, flags);
head = pcap->adc_head;
if (!pcap->adc_queue[head]) {
/* queue is empty, save power */
pcap_disable_adc(pcap);
mutex_unlock(&pcap->adc_mutex);
spin_unlock_irqrestore(&pcap->adc_lock, flags);
return;
}
/* start conversion on requested bank, save TS_M bits */
@ -254,7 +259,7 @@ static void pcap_adc_trigger(struct pcap_chip *pcap)
tmp |= PCAP_ADC_AD_SEL1;
ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
mutex_unlock(&pcap->adc_mutex);
spin_unlock_irqrestore(&pcap->adc_lock, flags);
ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC);
}
@ -265,11 +270,11 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap)
u16 res[2];
u32 tmp;
mutex_lock(&pcap->adc_mutex);
spin_lock(&pcap->adc_lock);
req = pcap->adc_queue[pcap->adc_head];
if (WARN(!req, "adc irq without pending request\n")) {
mutex_unlock(&pcap->adc_mutex);
spin_unlock(&pcap->adc_lock);
return IRQ_HANDLED;
}
@ -285,7 +290,7 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap)
pcap->adc_queue[pcap->adc_head] = NULL;
pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1);
mutex_unlock(&pcap->adc_mutex);
spin_unlock(&pcap->adc_lock);
/* pass the results and release memory */
req->callback(req->data, res);
@ -301,6 +306,7 @@ int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
void *callback, void *data)
{
struct pcap_adc_request *req;
unsigned long irq_flags;
/* This will be freed after we have a result */
req = kmalloc(sizeof(struct pcap_adc_request), GFP_KERNEL);
@ -314,15 +320,15 @@ int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
req->callback = callback;
req->data = data;
mutex_lock(&pcap->adc_mutex);
spin_lock_irqsave(&pcap->adc_lock, irq_flags);
if (pcap->adc_queue[pcap->adc_tail]) {
mutex_unlock(&pcap->adc_mutex);
spin_unlock_irqrestore(&pcap->adc_lock, irq_flags);
kfree(req);
return -EBUSY;
}
pcap->adc_queue[pcap->adc_tail] = req;
pcap->adc_tail = (pcap->adc_tail + 1) & (PCAP_ADC_MAXQ - 1);
mutex_unlock(&pcap->adc_mutex);
spin_unlock_irqrestore(&pcap->adc_lock, irq_flags);
/* start conversion */
pcap_adc_trigger(pcap);
@ -389,16 +395,17 @@ static int pcap_add_subdev(struct pcap_chip *pcap,
static int ezx_pcap_remove(struct spi_device *spi)
{
struct pcap_chip *pcap = spi_get_drvdata(spi);
unsigned long flags;
int i;
/* remove all registered subdevs */
device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
/* cleanup ADC */
mutex_lock(&pcap->adc_mutex);
spin_lock_irqsave(&pcap->adc_lock, flags);
for (i = 0; i < PCAP_ADC_MAXQ; i++)
kfree(pcap->adc_queue[i]);
mutex_unlock(&pcap->adc_mutex);
spin_unlock_irqrestore(&pcap->adc_lock, flags);
/* cleanup irqchip */
for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
@ -426,8 +433,8 @@ static int ezx_pcap_probe(struct spi_device *spi)
goto ret;
}
mutex_init(&pcap->io_mutex);
mutex_init(&pcap->adc_mutex);
spin_lock_init(&pcap->io_lock);
spin_lock_init(&pcap->adc_lock);
INIT_WORK(&pcap->isr_work, pcap_isr_work);
INIT_WORK(&pcap->msr_work, pcap_msr_work);
spi_set_drvdata(spi, pcap);

View File

@ -69,10 +69,8 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,
int irq;
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(dev, "Failed to get irq\n");
if (irq <= 0)
return irq;
}
tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops,
tsadc);

View File

@ -385,8 +385,7 @@ static void htcpld_unregister_chip_i2c(
htcpld = platform_get_drvdata(pdev);
chip = &htcpld->chip[chip_index];
if (chip->client)
i2c_unregister_device(chip->client);
i2c_unregister_device(chip->client);
}
static int htcpld_register_chip_gpio(

View File

@ -18,6 +18,10 @@
#include "intel-lpss.h"
static const struct intel_lpss_platform_info spt_info = {
.clk_rate = 120000000,
};
static struct property_entry spt_i2c_properties[] = {
PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230),
{ },
@ -28,6 +32,19 @@ static const struct intel_lpss_platform_info spt_i2c_info = {
.properties = spt_i2c_properties,
};
static struct property_entry uart_properties[] = {
PROPERTY_ENTRY_U32("reg-io-width", 4),
PROPERTY_ENTRY_U32("reg-shift", 2),
PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"),
{ },
};
static const struct intel_lpss_platform_info spt_uart_info = {
.clk_rate = 120000000,
.clk_con_id = "baudclk",
.properties = uart_properties,
};
static const struct intel_lpss_platform_info bxt_info = {
.clk_rate = 100000000,
};
@ -58,8 +75,17 @@ static const struct intel_lpss_platform_info apl_i2c_info = {
static const struct acpi_device_id intel_lpss_acpi_ids[] = {
/* SPT */
{ "INT3440", (kernel_ulong_t)&spt_info },
{ "INT3441", (kernel_ulong_t)&spt_info },
{ "INT3442", (kernel_ulong_t)&spt_i2c_info },
{ "INT3443", (kernel_ulong_t)&spt_i2c_info },
{ "INT3444", (kernel_ulong_t)&spt_i2c_info },
{ "INT3445", (kernel_ulong_t)&spt_i2c_info },
{ "INT3446", (kernel_ulong_t)&spt_i2c_info },
{ "INT3447", (kernel_ulong_t)&spt_i2c_info },
{ "INT3448", (kernel_ulong_t)&spt_uart_info },
{ "INT3449", (kernel_ulong_t)&spt_uart_info },
{ "INT344A", (kernel_ulong_t)&spt_uart_info },
/* BXT */
{ "80860AAC", (kernel_ulong_t)&bxt_i2c_info },
{ "80860ABC", (kernel_ulong_t)&bxt_info },

View File

@ -35,6 +35,8 @@ static int intel_lpss_pci_probe(struct pci_dev *pdev,
info->mem = &pdev->resource[0];
info->irq = pdev->irq;
pdev->d3cold_delay = 0;
/* Probably it is enough to set this for iDMA capable devices only */
pci_set_master(pdev);
pci_try_set_mwi(pdev);
@ -256,6 +258,29 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&cnl_i2c_info },
{ PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&cnl_i2c_info },
{ PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&spt_info },
/* TGL-LP */
{ PCI_VDEVICE(INTEL, 0xa0a8), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0xa0a9), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0xa0aa), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0xa0ab), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0xa0c5), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa0c6), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa0c7), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0xa0d8), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa0d9), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa0da), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0xa0db), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0xa0dc), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0xa0dd), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0xa0de), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0xa0df), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0xa0e8), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa0e9), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa0ea), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa0eb), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa0fb), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0xa0fd), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0xa0fe), (kernel_ulong_t)&spt_info },
/* SPT-H */
{ PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info },
{ PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info },

View File

@ -47,10 +47,10 @@
#define LPSS_PRIV_IDLELTR 0x14
#define LPSS_PRIV_LTR_REQ BIT(15)
#define LPSS_PRIV_LTR_SCALE_MASK 0xc00
#define LPSS_PRIV_LTR_SCALE_1US 0x800
#define LPSS_PRIV_LTR_SCALE_32US 0xc00
#define LPSS_PRIV_LTR_VALUE_MASK 0x3ff
#define LPSS_PRIV_LTR_SCALE_MASK GENMASK(11, 10)
#define LPSS_PRIV_LTR_SCALE_1US (2 << 10)
#define LPSS_PRIV_LTR_SCALE_32US (3 << 10)
#define LPSS_PRIV_LTR_VALUE_MASK GENMASK(9, 0)
#define LPSS_PRIV_SSP_REG 0x20
#define LPSS_PRIV_SSP_REG_DIS_DMA_FIN BIT(0)
@ -59,8 +59,8 @@
#define LPSS_PRIV_CAPS 0xfc
#define LPSS_PRIV_CAPS_NO_IDMA BIT(8)
#define LPSS_PRIV_CAPS_TYPE_MASK GENMASK(7, 4)
#define LPSS_PRIV_CAPS_TYPE_SHIFT 4
#define LPSS_PRIV_CAPS_TYPE_MASK (0xf << LPSS_PRIV_CAPS_TYPE_SHIFT)
/* This matches the type field in CAPS register */
enum intel_lpss_dev_type {
@ -128,17 +128,6 @@ static const struct mfd_cell intel_lpss_spi_cell = {
static DEFINE_IDA(intel_lpss_devid_ida);
static struct dentry *intel_lpss_debugfs;
static int intel_lpss_request_dma_module(const char *name)
{
static bool intel_lpss_dma_requested;
if (intel_lpss_dma_requested)
return 0;
intel_lpss_dma_requested = true;
return request_module("%s", name);
}
static void intel_lpss_cache_ltr(struct intel_lpss *lpss)
{
lpss->active_ltr = readl(lpss->priv + LPSS_PRIV_ACTIVELTR);
@ -429,16 +418,6 @@ int intel_lpss_probe(struct device *dev,
dev_warn(dev, "Failed to create debugfs entries\n");
if (intel_lpss_has_idma(lpss)) {
/*
* Ensure the DMA driver is loaded before the host
* controller device appears, so that the host controller
* driver can request its DMA channels as early as
* possible.
*
* If the DMA module is not there that's OK as well.
*/
intel_lpss_request_dma_module(LPSS_IDMA64_DRIVER_NAME);
ret = mfd_add_devices(dev, lpss->devid, &intel_lpss_idma64_cell,
1, info->mem, info->irq, NULL);
if (ret)
@ -554,3 +533,11 @@ MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
MODULE_DESCRIPTION("Intel LPSS core driver");
MODULE_LICENSE("GPL v2");
/*
* Ensure the DMA driver is loaded before the host controller device appears,
* so that the host controller driver can request its DMA channels as early
* as possible.
*
* If the DMA module is not there that's OK as well.
*/
MODULE_SOFTDEP("pre: platform:" LPSS_IDMA64_DRIVER_NAME);

View File

@ -450,10 +450,8 @@ static int bxtwc_probe(struct platform_device *pdev)
return -ENOMEM;
ret = platform_get_irq(pdev, 0);
if (ret < 0) {
dev_err(&pdev->dev, "Invalid IRQ\n");
if (ret < 0)
return ret;
}
pmic->irq = ret;
dev_set_drvdata(&pdev->dev, pmic);

View File

@ -0,0 +1,157 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Device access for Basin Cove PMIC
*
* Copyright (c) 2019, Intel Corporation.
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/
#include <linux/acpi.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/intel_soc_pmic.h>
#include <linux/mfd/intel_soc_pmic_mrfld.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <asm/intel_scu_ipc.h>
/*
* Level 2 IRQs
*
* Firmware on the systems with Basin Cove PMIC services Level 1 IRQs
* without an assistance. Thus, each of the Level 1 IRQ is represented
* as a separate RTE in IOAPIC.
*/
static struct resource irq_level2_resources[] = {
DEFINE_RES_IRQ(0), /* power button */
DEFINE_RES_IRQ(0), /* TMU */
DEFINE_RES_IRQ(0), /* thermal */
DEFINE_RES_IRQ(0), /* BCU */
DEFINE_RES_IRQ(0), /* ADC */
DEFINE_RES_IRQ(0), /* charger */
DEFINE_RES_IRQ(0), /* GPIO */
};
static const struct mfd_cell bcove_dev[] = {
{
.name = "mrfld_bcove_pwrbtn",
.num_resources = 1,
.resources = &irq_level2_resources[0],
}, {
.name = "mrfld_bcove_tmu",
.num_resources = 1,
.resources = &irq_level2_resources[1],
}, {
.name = "mrfld_bcove_thermal",
.num_resources = 1,
.resources = &irq_level2_resources[2],
}, {
.name = "mrfld_bcove_bcu",
.num_resources = 1,
.resources = &irq_level2_resources[3],
}, {
.name = "mrfld_bcove_adc",
.num_resources = 1,
.resources = &irq_level2_resources[4],
}, {
.name = "mrfld_bcove_charger",
.num_resources = 1,
.resources = &irq_level2_resources[5],
}, {
.name = "mrfld_bcove_pwrsrc",
.num_resources = 1,
.resources = &irq_level2_resources[5],
}, {
.name = "mrfld_bcove_gpio",
.num_resources = 1,
.resources = &irq_level2_resources[6],
},
{ .name = "mrfld_bcove_region", },
};
static int bcove_ipc_byte_reg_read(void *context, unsigned int reg,
unsigned int *val)
{
u8 ipc_out;
int ret;
ret = intel_scu_ipc_ioread8(reg, &ipc_out);
if (ret)
return ret;
*val = ipc_out;
return 0;
}
static int bcove_ipc_byte_reg_write(void *context, unsigned int reg,
unsigned int val)
{
u8 ipc_in = val;
int ret;
ret = intel_scu_ipc_iowrite8(reg, ipc_in);
if (ret)
return ret;
return 0;
}
static const struct regmap_config bcove_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.max_register = 0xff,
.reg_write = bcove_ipc_byte_reg_write,
.reg_read = bcove_ipc_byte_reg_read,
};
static int bcove_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct intel_soc_pmic *pmic;
unsigned int i;
int ret;
pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
platform_set_drvdata(pdev, pmic);
pmic->dev = &pdev->dev;
pmic->regmap = devm_regmap_init(dev, NULL, pmic, &bcove_regmap_config);
if (IS_ERR(pmic->regmap))
return PTR_ERR(pmic->regmap);
for (i = 0; i < ARRAY_SIZE(irq_level2_resources); i++) {
ret = platform_get_irq(pdev, i);
if (ret < 0)
return ret;
irq_level2_resources[i].start = ret;
irq_level2_resources[i].end = ret;
}
return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
bcove_dev, ARRAY_SIZE(bcove_dev),
NULL, 0, NULL);
}
static const struct acpi_device_id bcove_acpi_ids[] = {
{ "INTC100E" },
{}
};
MODULE_DEVICE_TABLE(acpi, bcove_acpi_ids);
static struct platform_driver bcove_driver = {
.driver = {
.name = "intel_soc_pmic_mrfld",
.acpi_match_table = bcove_acpi_ids,
},
.probe = bcove_probe,
};
module_platform_driver(bcove_driver);
MODULE_DESCRIPTION("IPC driver for Intel SoC Basin Cove PMIC");
MODULE_LICENSE("GPL v2");

View File

@ -1,324 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 SoC ADC driver
*
* This driver synchronizes access to the JZ4740 ADC core between the
* JZ4740 battery and hwmon drivers.
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/mfd/core.h>
#include <linux/jz4740-adc.h>
#define JZ_REG_ADC_ENABLE 0x00
#define JZ_REG_ADC_CFG 0x04
#define JZ_REG_ADC_CTRL 0x08
#define JZ_REG_ADC_STATUS 0x0c
#define JZ_REG_ADC_TOUCHSCREEN_BASE 0x10
#define JZ_REG_ADC_BATTERY_BASE 0x1c
#define JZ_REG_ADC_HWMON_BASE 0x20
#define JZ_ADC_ENABLE_TOUCH BIT(2)
#define JZ_ADC_ENABLE_BATTERY BIT(1)
#define JZ_ADC_ENABLE_ADCIN BIT(0)
enum {
JZ_ADC_IRQ_ADCIN = 0,
JZ_ADC_IRQ_BATTERY,
JZ_ADC_IRQ_TOUCH,
JZ_ADC_IRQ_PENUP,
JZ_ADC_IRQ_PENDOWN,
};
struct jz4740_adc {
struct resource *mem;
void __iomem *base;
int irq;
struct irq_chip_generic *gc;
struct clk *clk;
atomic_t clk_ref;
spinlock_t lock;
};
static void jz4740_adc_irq_demux(struct irq_desc *desc)
{
struct irq_chip_generic *gc = irq_desc_get_handler_data(desc);
uint8_t status;
unsigned int i;
status = readb(gc->reg_base + JZ_REG_ADC_STATUS);
for (i = 0; i < 5; ++i) {
if (status & BIT(i))
generic_handle_irq(gc->irq_base + i);
}
}
/* Refcounting for the ADC clock is done in here instead of in the clock
* framework, because it is the only clock which is shared between multiple
* devices and thus is the only clock which needs refcounting */
static inline void jz4740_adc_clk_enable(struct jz4740_adc *adc)
{
if (atomic_inc_return(&adc->clk_ref) == 1)
clk_prepare_enable(adc->clk);
}
static inline void jz4740_adc_clk_disable(struct jz4740_adc *adc)
{
if (atomic_dec_return(&adc->clk_ref) == 0)
clk_disable_unprepare(adc->clk);
}
static inline void jz4740_adc_set_enabled(struct jz4740_adc *adc, int engine,
bool enabled)
{
unsigned long flags;
uint8_t val;
spin_lock_irqsave(&adc->lock, flags);
val = readb(adc->base + JZ_REG_ADC_ENABLE);
if (enabled)
val |= BIT(engine);
else
val &= ~BIT(engine);
writeb(val, adc->base + JZ_REG_ADC_ENABLE);
spin_unlock_irqrestore(&adc->lock, flags);
}
static int jz4740_adc_cell_enable(struct platform_device *pdev)
{
struct jz4740_adc *adc = dev_get_drvdata(pdev->dev.parent);
jz4740_adc_clk_enable(adc);
jz4740_adc_set_enabled(adc, pdev->id, true);
return 0;
}
static int jz4740_adc_cell_disable(struct platform_device *pdev)
{
struct jz4740_adc *adc = dev_get_drvdata(pdev->dev.parent);
jz4740_adc_set_enabled(adc, pdev->id, false);
jz4740_adc_clk_disable(adc);
return 0;
}
int jz4740_adc_set_config(struct device *dev, uint32_t mask, uint32_t val)
{
struct jz4740_adc *adc = dev_get_drvdata(dev);
unsigned long flags;
uint32_t cfg;
if (!adc)
return -ENODEV;
spin_lock_irqsave(&adc->lock, flags);
cfg = readl(adc->base + JZ_REG_ADC_CFG);
cfg &= ~mask;
cfg |= val;
writel(cfg, adc->base + JZ_REG_ADC_CFG);
spin_unlock_irqrestore(&adc->lock, flags);
return 0;
}
EXPORT_SYMBOL_GPL(jz4740_adc_set_config);
static struct resource jz4740_hwmon_resources[] = {
{
.start = JZ_ADC_IRQ_ADCIN,
.flags = IORESOURCE_IRQ,
},
{
.start = JZ_REG_ADC_HWMON_BASE,
.end = JZ_REG_ADC_HWMON_BASE + 3,
.flags = IORESOURCE_MEM,
},
};
static struct resource jz4740_battery_resources[] = {
{
.start = JZ_ADC_IRQ_BATTERY,
.flags = IORESOURCE_IRQ,
},
{
.start = JZ_REG_ADC_BATTERY_BASE,
.end = JZ_REG_ADC_BATTERY_BASE + 3,
.flags = IORESOURCE_MEM,
},
};
static const struct mfd_cell jz4740_adc_cells[] = {
{
.id = 0,
.name = "jz4740-hwmon",
.num_resources = ARRAY_SIZE(jz4740_hwmon_resources),
.resources = jz4740_hwmon_resources,
.enable = jz4740_adc_cell_enable,
.disable = jz4740_adc_cell_disable,
},
{
.id = 1,
.name = "jz4740-battery",
.num_resources = ARRAY_SIZE(jz4740_battery_resources),
.resources = jz4740_battery_resources,
.enable = jz4740_adc_cell_enable,
.disable = jz4740_adc_cell_disable,
},
};
static int jz4740_adc_probe(struct platform_device *pdev)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
struct jz4740_adc *adc;
struct resource *mem_base;
int ret;
int irq_base;
adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL);
if (!adc)
return -ENOMEM;
adc->irq = platform_get_irq(pdev, 0);
if (adc->irq < 0) {
ret = adc->irq;
dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
return ret;
}
irq_base = platform_get_irq(pdev, 1);
if (irq_base < 0) {
dev_err(&pdev->dev, "Failed to get irq base: %d\n", irq_base);
return irq_base;
}
mem_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem_base) {
dev_err(&pdev->dev, "Failed to get platform mmio resource\n");
return -ENOENT;
}
/* Only request the shared registers for the MFD driver */
adc->mem = request_mem_region(mem_base->start, JZ_REG_ADC_STATUS,
pdev->name);
if (!adc->mem) {
dev_err(&pdev->dev, "Failed to request mmio memory region\n");
return -EBUSY;
}
adc->base = ioremap_nocache(adc->mem->start, resource_size(adc->mem));
if (!adc->base) {
ret = -EBUSY;
dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
goto err_release_mem_region;
}
adc->clk = clk_get(&pdev->dev, "adc");
if (IS_ERR(adc->clk)) {
ret = PTR_ERR(adc->clk);
dev_err(&pdev->dev, "Failed to get clock: %d\n", ret);
goto err_iounmap;
}
spin_lock_init(&adc->lock);
atomic_set(&adc->clk_ref, 0);
platform_set_drvdata(pdev, adc);
gc = irq_alloc_generic_chip("INTC", 1, irq_base, adc->base,
handle_level_irq);
ct = gc->chip_types;
ct->regs.mask = JZ_REG_ADC_CTRL;
ct->regs.ack = JZ_REG_ADC_STATUS;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
ct->chip.irq_ack = irq_gc_ack_set_bit;
irq_setup_generic_chip(gc, IRQ_MSK(5), IRQ_GC_INIT_MASK_CACHE, 0,
IRQ_NOPROBE | IRQ_LEVEL);
adc->gc = gc;
irq_set_chained_handler_and_data(adc->irq, jz4740_adc_irq_demux, gc);
writeb(0x00, adc->base + JZ_REG_ADC_ENABLE);
writeb(0xff, adc->base + JZ_REG_ADC_CTRL);
ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells,
ARRAY_SIZE(jz4740_adc_cells), mem_base,
irq_base, NULL);
if (ret < 0)
goto err_clk_put;
return 0;
err_clk_put:
clk_put(adc->clk);
err_iounmap:
iounmap(adc->base);
err_release_mem_region:
release_mem_region(adc->mem->start, resource_size(adc->mem));
return ret;
}
static int jz4740_adc_remove(struct platform_device *pdev)
{
struct jz4740_adc *adc = platform_get_drvdata(pdev);
mfd_remove_devices(&pdev->dev);
irq_remove_generic_chip(adc->gc, IRQ_MSK(5), IRQ_NOPROBE | IRQ_LEVEL, 0);
kfree(adc->gc);
irq_set_chained_handler_and_data(adc->irq, NULL, NULL);
iounmap(adc->base);
release_mem_region(adc->mem->start, resource_size(adc->mem));
clk_put(adc->clk);
return 0;
}
static struct platform_driver jz4740_adc_driver = {
.probe = jz4740_adc_probe,
.remove = jz4740_adc_remove,
.driver = {
.name = "jz4740-adc",
},
};
module_platform_driver(jz4740_adc_driver);
MODULE_DESCRIPTION("JZ4740 SoC ADC driver");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:jz4740-adc");

View File

@ -297,11 +297,11 @@ static int max77836_init(struct max14577 *max14577)
int ret;
u8 intsrc_mask;
max14577->i2c_pmic = i2c_new_dummy(max14577->i2c->adapter,
max14577->i2c_pmic = i2c_new_dummy_device(max14577->i2c->adapter,
I2C_ADDR_PMIC);
if (!max14577->i2c_pmic) {
if (IS_ERR(max14577->i2c_pmic)) {
dev_err(max14577->dev, "Failed to register PMIC I2C device\n");
return -ENODEV;
return PTR_ERR(max14577->i2c_pmic);
}
i2c_set_clientdata(max14577->i2c_pmic, max14577);

View File

@ -416,8 +416,10 @@ static int max77620_initialise_fps(struct max77620_chip *chip)
for_each_child_of_node(fps_np, fps_child) {
ret = max77620_config_fps(chip, fps_child);
if (ret < 0)
if (ret < 0) {
of_node_put(fps_child);
return ret;
}
}
config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0;

View File

@ -183,17 +183,17 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
} else
dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
max77693->i2c_muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
if (!max77693->i2c_muic) {
max77693->i2c_muic = i2c_new_dummy_device(i2c->adapter, I2C_ADDR_MUIC);
if (IS_ERR(max77693->i2c_muic)) {
dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n");
return -ENODEV;
return PTR_ERR(max77693->i2c_muic);
}
i2c_set_clientdata(max77693->i2c_muic, max77693);
max77693->i2c_haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
if (!max77693->i2c_haptic) {
max77693->i2c_haptic = i2c_new_dummy_device(i2c->adapter, I2C_ADDR_HAPTIC);
if (IS_ERR(max77693->i2c_haptic)) {
dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n");
ret = -ENODEV;
ret = PTR_ERR(max77693->i2c_haptic);
goto err_i2c_haptic;
}
i2c_set_clientdata(max77693->i2c_haptic, max77693);

View File

@ -70,11 +70,11 @@ static int max77843_chg_init(struct max77693_dev *max77843)
{
int ret;
max77843->i2c_chg = i2c_new_dummy(max77843->i2c->adapter, I2C_ADDR_CHG);
if (!max77843->i2c_chg) {
max77843->i2c_chg = i2c_new_dummy_device(max77843->i2c->adapter, I2C_ADDR_CHG);
if (IS_ERR(max77843->i2c_chg)) {
dev_err(&max77843->i2c->dev,
"Cannot allocate I2C device for Charger\n");
return -ENODEV;
return PTR_ERR(max77843->i2c_chg);
}
i2c_set_clientdata(max77843->i2c_chg, max77843);

View File

@ -214,9 +214,9 @@ static int max8907_i2c_probe(struct i2c_client *i2c,
goto err_regmap_gen;
}
max8907->i2c_rtc = i2c_new_dummy(i2c->adapter, MAX8907_RTC_I2C_ADDR);
if (!max8907->i2c_rtc) {
ret = -ENOMEM;
max8907->i2c_rtc = i2c_new_dummy_device(i2c->adapter, MAX8907_RTC_I2C_ADDR);
if (IS_ERR(max8907->i2c_rtc)) {
ret = PTR_ERR(max8907->i2c_rtc);
goto err_dummy_rtc;
}
i2c_set_clientdata(max8907->i2c_rtc, max8907);

View File

@ -176,18 +176,18 @@ static int max8925_probe(struct i2c_client *client,
dev_set_drvdata(chip->dev, chip);
mutex_init(&chip->io_lock);
chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
if (!chip->rtc) {
chip->rtc = i2c_new_dummy_device(chip->i2c->adapter, RTC_I2C_ADDR);
if (IS_ERR(chip->rtc)) {
dev_err(chip->dev, "Failed to allocate I2C device for RTC\n");
return -ENODEV;
return PTR_ERR(chip->rtc);
}
i2c_set_clientdata(chip->rtc, chip);
chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
if (!chip->adc) {
chip->adc = i2c_new_dummy_device(chip->i2c->adapter, ADC_I2C_ADDR);
if (IS_ERR(chip->adc)) {
dev_err(chip->dev, "Failed to allocate I2C device for ADC\n");
i2c_unregister_device(chip->rtc);
return -ENODEV;
return PTR_ERR(chip->adc);
}
i2c_set_clientdata(chip->adc, chip);

View File

@ -185,25 +185,25 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
mutex_init(&max8997->iolock);
max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
if (!max8997->rtc) {
max8997->rtc = i2c_new_dummy_device(i2c->adapter, I2C_ADDR_RTC);
if (IS_ERR(max8997->rtc)) {
dev_err(max8997->dev, "Failed to allocate I2C device for RTC\n");
return -ENODEV;
return PTR_ERR(max8997->rtc);
}
i2c_set_clientdata(max8997->rtc, max8997);
max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
if (!max8997->haptic) {
max8997->haptic = i2c_new_dummy_device(i2c->adapter, I2C_ADDR_HAPTIC);
if (IS_ERR(max8997->haptic)) {
dev_err(max8997->dev, "Failed to allocate I2C device for Haptic\n");
ret = -ENODEV;
ret = PTR_ERR(max8997->haptic);
goto err_i2c_haptic;
}
i2c_set_clientdata(max8997->haptic, max8997);
max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
if (!max8997->muic) {
max8997->muic = i2c_new_dummy_device(i2c->adapter, I2C_ADDR_MUIC);
if (IS_ERR(max8997->muic)) {
dev_err(max8997->dev, "Failed to allocate I2C device for MUIC\n");
ret = -ENODEV;
ret = PTR_ERR(max8997->muic);
goto err_i2c_muic;
}
i2c_set_clientdata(max8997->muic, max8997);

View File

@ -195,10 +195,10 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
}
mutex_init(&max8998->iolock);
max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
if (!max8998->rtc) {
max8998->rtc = i2c_new_dummy_device(i2c->adapter, RTC_I2C_ADDR);
if (IS_ERR(max8998->rtc)) {
dev_err(&i2c->dev, "Failed to allocate I2C device for RTC\n");
return -ENODEV;
return PTR_ERR(max8998->rtc);
}
i2c_set_clientdata(max8998->rtc, max8998);

View File

@ -5,34 +5,34 @@
*/
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/regmap.h>
#include <linux/mfd/core.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/core.h>
#include <linux/mfd/mt6397/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/registers.h>
#include <linux/mfd/mt6397/registers.h>
#define MT6323_RTC_BASE 0x8000
#define MT6323_RTC_SIZE 0x40
#define MT6397_RTC_BASE 0xe000
#define MT6397_RTC_SIZE 0x3e
#define MT6323_CID_CODE 0x23
#define MT6391_CID_CODE 0x91
#define MT6397_CID_CODE 0x97
#define MT6323_PWRC_BASE 0x8000
#define MT6323_PWRC_SIZE 0x40
static const struct resource mt6323_rtc_resources[] = {
DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE),
DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),
};
static const struct resource mt6397_rtc_resources[] = {
{
.start = MT6397_RTC_BASE,
.end = MT6397_RTC_BASE + MT6397_RTC_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = MT6397_IRQ_RTC,
.end = MT6397_IRQ_RTC,
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
DEFINE_RES_IRQ(MT6397_IRQ_RTC),
};
static const struct resource mt6323_keys_resources[] = {
@ -45,8 +45,17 @@ static const struct resource mt6397_keys_resources[] = {
DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY),
};
static const struct resource mt6323_pwrc_resources[] = {
DEFINE_RES_MEM(MT6323_PWRC_BASE, MT6323_PWRC_SIZE),
};
static const struct mfd_cell mt6323_devs[] = {
{
.name = "mt6323-rtc",
.num_resources = ARRAY_SIZE(mt6323_rtc_resources),
.resources = mt6323_rtc_resources,
.of_compatible = "mediatek,mt6323-rtc",
}, {
.name = "mt6323-regulator",
.of_compatible = "mediatek,mt6323-regulator"
}, {
@ -57,6 +66,11 @@ static const struct mfd_cell mt6323_devs[] = {
.num_resources = ARRAY_SIZE(mt6323_keys_resources),
.resources = mt6323_keys_resources,
.of_compatible = "mediatek,mt6323-keys"
}, {
.name = "mt6323-pwrc",
.num_resources = ARRAY_SIZE(mt6323_pwrc_resources),
.resources = mt6323_pwrc_resources,
.of_compatible = "mediatek,mt6323-pwrc"
},
};
@ -86,148 +100,6 @@ static const struct mfd_cell mt6397_devs[] = {
}
};
static void mt6397_irq_lock(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
mutex_lock(&mt6397->irqlock);
}
static void mt6397_irq_sync_unlock(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
regmap_write(mt6397->regmap, mt6397->int_con[0],
mt6397->irq_masks_cur[0]);
regmap_write(mt6397->regmap, mt6397->int_con[1],
mt6397->irq_masks_cur[1]);
mutex_unlock(&mt6397->irqlock);
}
static void mt6397_irq_disable(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
int shift = data->hwirq & 0xf;
int reg = data->hwirq >> 4;
mt6397->irq_masks_cur[reg] &= ~BIT(shift);
}
static void mt6397_irq_enable(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
int shift = data->hwirq & 0xf;
int reg = data->hwirq >> 4;
mt6397->irq_masks_cur[reg] |= BIT(shift);
}
#ifdef CONFIG_PM_SLEEP
static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
int shift = irq_data->hwirq & 0xf;
int reg = irq_data->hwirq >> 4;
if (on)
mt6397->wake_mask[reg] |= BIT(shift);
else
mt6397->wake_mask[reg] &= ~BIT(shift);
return 0;
}
#else
#define mt6397_irq_set_wake NULL
#endif
static struct irq_chip mt6397_irq_chip = {
.name = "mt6397-irq",
.irq_bus_lock = mt6397_irq_lock,
.irq_bus_sync_unlock = mt6397_irq_sync_unlock,
.irq_enable = mt6397_irq_enable,
.irq_disable = mt6397_irq_disable,
.irq_set_wake = mt6397_irq_set_wake,
};
static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
int irqbase)
{
unsigned int status;
int i, irq, ret;
ret = regmap_read(mt6397->regmap, reg, &status);
if (ret) {
dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
return;
}
for (i = 0; i < 16; i++) {
if (status & BIT(i)) {
irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
if (irq)
handle_nested_irq(irq);
}
}
regmap_write(mt6397->regmap, reg, status);
}
static irqreturn_t mt6397_irq_thread(int irq, void *data)
{
struct mt6397_chip *mt6397 = data;
mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
return IRQ_HANDLED;
}
static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
struct mt6397_chip *mt6397 = d->host_data;
irq_set_chip_data(irq, mt6397);
irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
irq_set_nested_thread(irq, 1);
irq_set_noprobe(irq);
return 0;
}
static const struct irq_domain_ops mt6397_irq_domain_ops = {
.map = mt6397_irq_domain_map,
};
static int mt6397_irq_init(struct mt6397_chip *mt6397)
{
int ret;
mutex_init(&mt6397->irqlock);
/* Mask all interrupt sources */
regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
if (!mt6397->irq_domain) {
dev_err(mt6397->dev, "could not create irq domain\n");
return -ENOMEM;
}
ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL,
mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397);
if (ret) {
dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n",
mt6397->irq, ret);
return ret;
}
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int mt6397_irq_suspend(struct device *dev)
{
@ -290,7 +162,7 @@ static int mt6397_probe(struct platform_device *pdev)
return pmic->irq;
switch (id & 0xff) {
case MT6323_CID_CODE:
case MT6323_CHIP_ID:
pmic->int_con[0] = MT6323_INT_CON0;
pmic->int_con[1] = MT6323_INT_CON1;
pmic->int_status[0] = MT6323_INT_STATUS0;
@ -304,8 +176,8 @@ static int mt6397_probe(struct platform_device *pdev)
0, pmic->irq_domain);
break;
case MT6397_CID_CODE:
case MT6391_CID_CODE:
case MT6391_CHIP_ID:
case MT6397_CHIP_ID:
pmic->int_con[0] = MT6397_INT_CON0;
pmic->int_con[1] = MT6397_INT_CON1;
pmic->int_status[0] = MT6397_INT_STATUS0;

View File

@ -0,0 +1,181 @@
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2019 MediaTek Inc.
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/mfd/mt6323/core.h>
#include <linux/mfd/mt6323/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6397/registers.h>
static void mt6397_irq_lock(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
mutex_lock(&mt6397->irqlock);
}
static void mt6397_irq_sync_unlock(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
regmap_write(mt6397->regmap, mt6397->int_con[0],
mt6397->irq_masks_cur[0]);
regmap_write(mt6397->regmap, mt6397->int_con[1],
mt6397->irq_masks_cur[1]);
mutex_unlock(&mt6397->irqlock);
}
static void mt6397_irq_disable(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
int shift = data->hwirq & 0xf;
int reg = data->hwirq >> 4;
mt6397->irq_masks_cur[reg] &= ~BIT(shift);
}
static void mt6397_irq_enable(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
int shift = data->hwirq & 0xf;
int reg = data->hwirq >> 4;
mt6397->irq_masks_cur[reg] |= BIT(shift);
}
#ifdef CONFIG_PM_SLEEP
static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
int shift = irq_data->hwirq & 0xf;
int reg = irq_data->hwirq >> 4;
if (on)
mt6397->wake_mask[reg] |= BIT(shift);
else
mt6397->wake_mask[reg] &= ~BIT(shift);
return 0;
}
#else
#define mt6397_irq_set_wake NULL
#endif
static struct irq_chip mt6397_irq_chip = {
.name = "mt6397-irq",
.irq_bus_lock = mt6397_irq_lock,
.irq_bus_sync_unlock = mt6397_irq_sync_unlock,
.irq_enable = mt6397_irq_enable,
.irq_disable = mt6397_irq_disable,
.irq_set_wake = mt6397_irq_set_wake,
};
static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
int irqbase)
{
unsigned int status;
int i, irq, ret;
ret = regmap_read(mt6397->regmap, reg, &status);
if (ret) {
dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
return;
}
for (i = 0; i < 16; i++) {
if (status & BIT(i)) {
irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
if (irq)
handle_nested_irq(irq);
}
}
regmap_write(mt6397->regmap, reg, status);
}
static irqreturn_t mt6397_irq_thread(int irq, void *data)
{
struct mt6397_chip *mt6397 = data;
mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
return IRQ_HANDLED;
}
static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
struct mt6397_chip *mt6397 = d->host_data;
irq_set_chip_data(irq, mt6397);
irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
irq_set_nested_thread(irq, 1);
irq_set_noprobe(irq);
return 0;
}
static const struct irq_domain_ops mt6397_irq_domain_ops = {
.map = mt6397_irq_domain_map,
};
int mt6397_irq_init(struct mt6397_chip *chip)
{
int ret;
mutex_init(&chip->irqlock);
switch (chip->chip_id) {
case MT6323_CHIP_ID:
chip->int_con[0] = MT6323_INT_CON0;
chip->int_con[1] = MT6323_INT_CON1;
chip->int_status[0] = MT6323_INT_STATUS0;
chip->int_status[1] = MT6323_INT_STATUS1;
break;
case MT6391_CHIP_ID:
case MT6397_CHIP_ID:
chip->int_con[0] = MT6397_INT_CON0;
chip->int_con[1] = MT6397_INT_CON1;
chip->int_status[0] = MT6397_INT_STATUS0;
chip->int_status[1] = MT6397_INT_STATUS1;
break;
default:
dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
return -ENODEV;
}
/* Mask all interrupt sources */
regmap_write(chip->regmap, chip->int_con[0], 0x0);
regmap_write(chip->regmap, chip->int_con[1], 0x0);
chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
MT6397_IRQ_NR,
&mt6397_irq_domain_ops,
chip);
if (!chip->irq_domain) {
dev_err(chip->dev, "could not create irq domain\n");
return -ENOMEM;
}
ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL,
mt6397_irq_thread, IRQF_ONESHOT,
"mt6397-pmic", chip);
if (ret) {
dev_err(chip->dev, "failed to register irq=%d; err: %d\n",
chip->irq, ret);
return ret;
}
return 0;
}

View File

@ -549,12 +549,12 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
palmas->i2c_clients[i] = i2c;
else {
palmas->i2c_clients[i] =
i2c_new_dummy(i2c->adapter,
i2c_new_dummy_device(i2c->adapter,
i2c->addr + i);
if (!palmas->i2c_clients[i]) {
if (IS_ERR(palmas->i2c_clients[i])) {
dev_err(palmas->dev,
"can't attach client %d\n", i);
ret = -ENOMEM;
ret = PTR_ERR(palmas->i2c_clients[i]);
goto err_i2c;
}
palmas->i2c_clients[i]->dev.of_node = of_node_get(node);

View File

@ -561,22 +561,16 @@ static int qcom_rpm_probe(struct platform_device *pdev)
clk_prepare_enable(rpm->ramclk); /* Accepts NULL */
irq_ack = platform_get_irq_byname(pdev, "ack");
if (irq_ack < 0) {
dev_err(&pdev->dev, "required ack interrupt missing\n");
if (irq_ack < 0)
return irq_ack;
}
irq_err = platform_get_irq_byname(pdev, "err");
if (irq_err < 0) {
dev_err(&pdev->dev, "required err interrupt missing\n");
if (irq_err < 0)
return irq_err;
}
irq_wakeup = platform_get_irq_byname(pdev, "wakeup");
if (irq_wakeup < 0) {
dev_err(&pdev->dev, "required wakeup interrupt missing\n");
if (irq_wakeup < 0)
return irq_wakeup;
}
match = of_match_device(qcom_rpm_of_match, &pdev->dev);
if (!match)

View File

@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/platform_data/i2c-gpio.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
#include <linux/slab.h>
@ -1394,10 +1395,8 @@ static int sm501_plat_probe(struct platform_device *dev)
sm->platdata = dev_get_platdata(&dev->dev);
ret = platform_get_irq(dev, 0);
if (ret < 0) {
dev_err(&dev->dev, "failed to get irq resource\n");
if (ret < 0)
goto err_res;
}
sm->irq = ret;
sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);

View File

@ -626,8 +626,7 @@ static const struct mfd_cell timberdale_cells_bar2[] = {
static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct timberdale_device *priv = pci_get_drvdata(pdev);
struct timberdale_device *priv = dev_get_drvdata(dev);
return sprintf(buf, "%d.%d.%d\n", priv->fw.major, priv->fw.minor,
priv->fw.config);

View File

@ -437,12 +437,11 @@ static int tps80031_probe(struct i2c_client *client,
if (tps80031_slave_address[i] == client->addr)
tps80031->clients[i] = client;
else
tps80031->clients[i] = i2c_new_dummy(client->adapter,
tps80031_slave_address[i]);
if (!tps80031->clients[i]) {
tps80031->clients[i] = devm_i2c_new_dummy_device(&client->dev,
client->adapter, tps80031_slave_address[i]);
if (IS_ERR(tps80031->clients[i])) {
dev_err(&client->dev, "can't attach client %d\n", i);
ret = -ENOMEM;
goto fail_client_reg;
return PTR_ERR(tps80031->clients[i]);
}
i2c_set_clientdata(tps80031->clients[i], tps80031);
@ -452,7 +451,7 @@ static int tps80031_probe(struct i2c_client *client,
ret = PTR_ERR(tps80031->regmap[i]);
dev_err(&client->dev,
"regmap %d init failed, err %d\n", i, ret);
goto fail_client_reg;
return ret;
}
}
@ -461,7 +460,7 @@ static int tps80031_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(&client->dev,
"Silicon version number read failed: %d\n", ret);
goto fail_client_reg;
return ret;
}
ret = tps80031_read(&client->dev, TPS80031_SLAVE_ID3,
@ -469,7 +468,7 @@ static int tps80031_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(&client->dev,
"Silicon eeprom version read failed: %d\n", ret);
goto fail_client_reg;
return ret;
}
dev_info(&client->dev, "ES version 0x%02x and EPROM version 0x%02x\n",
@ -482,7 +481,7 @@ static int tps80031_probe(struct i2c_client *client,
ret = tps80031_irq_init(tps80031, client->irq, pdata->irq_base);
if (ret) {
dev_err(&client->dev, "IRQ init failed: %d\n", ret);
goto fail_client_reg;
return ret;
}
tps80031_pupd_init(tps80031, pdata);
@ -506,12 +505,6 @@ static int tps80031_probe(struct i2c_client *client,
fail_mfd_add:
regmap_del_irq_chip(client->irq, tps80031->irq_data);
fail_client_reg:
for (i = 0; i < TPS80031_NUM_SLAVES; i++) {
if (tps80031->clients[i] && (tps80031->clients[i] != client))
i2c_unregister_device(tps80031->clients[i]);
}
return ret;
}

View File

@ -1141,12 +1141,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (i == 0) {
twl->client = client;
} else {
twl->client = i2c_new_dummy(client->adapter,
twl->client = i2c_new_dummy_device(client->adapter,
client->addr + i);
if (!twl->client) {
if (IS_ERR(twl->client)) {
dev_err(&client->dev,
"can't attach client %d\n", i);
status = -ENOMEM;
status = PTR_ERR(twl->client);
goto fail;
}
}

View File

@ -312,7 +312,6 @@ header-test- += linux/mfd/as3711.h
header-test- += linux/mfd/as3722.h
header-test- += linux/mfd/da903x.h
header-test- += linux/mfd/da9055/pdata.h
header-test- += linux/mfd/da9063/pdata.h
header-test- += linux/mfd/db8500-prcmu.h
header-test- += linux/mfd/dbx500-prcmu.h
header-test- += linux/mfd/dln2.h

View File

@ -1,60 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Platform configuration options for DA9063
*
* Copyright 2012 Dialog Semiconductor Ltd.
*
* Author: Michal Hajduk, Dialog Semiconductor
* Author: Krystian Garbaciak, Dialog Semiconductor
*/
#ifndef __MFD_DA9063_PDATA_H__
#define __MFD_DA9063_PDATA_H__
/*
* RGB LED configuration
*/
/* LED IDs for flags in struct led_info. */
enum {
DA9063_GPIO11_LED,
DA9063_GPIO14_LED,
DA9063_GPIO15_LED,
DA9063_LED_NUM
};
#define DA9063_LED_ID_MASK 0x3
/* LED polarity for flags in struct led_info. */
#define DA9063_LED_HIGH_LEVEL_ACTIVE 0x0
#define DA9063_LED_LOW_LEVEL_ACTIVE 0x4
/*
* General PMIC configuration
*/
/* HWMON ADC channels configuration */
#define DA9063_FLG_FORCE_IN0_MANUAL_MODE 0x0010
#define DA9063_FLG_FORCE_IN0_AUTO_MODE 0x0020
#define DA9063_FLG_FORCE_IN1_MANUAL_MODE 0x0040
#define DA9063_FLG_FORCE_IN1_AUTO_MODE 0x0080
#define DA9063_FLG_FORCE_IN2_MANUAL_MODE 0x0100
#define DA9063_FLG_FORCE_IN2_AUTO_MODE 0x0200
#define DA9063_FLG_FORCE_IN3_MANUAL_MODE 0x0400
#define DA9063_FLG_FORCE_IN3_AUTO_MODE 0x0800
/* Disable register caching. */
#define DA9063_FLG_NO_CACHE 0x0008
struct da9063;
/* DA9063 platform data */
struct da9063_pdata {
int (*init)(struct da9063 *da9063);
int irq_base;
bool key_power;
unsigned flags;
struct da9063_regulators_pdata *regulators_pdata;
struct led_platform_data *leds_pdata;
};
#endif /* __MFD_DA9063_PDATA_H__ */

View File

@ -0,0 +1,81 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Header file for Intel Merrifield Basin Cove PMIC
*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*/
#ifndef __INTEL_SOC_PMIC_MRFLD_H__
#define __INTEL_SOC_PMIC_MRFLD_H__
#include <linux/bits.h>
#define BCOVE_ID 0x00
#define BCOVE_ID_MINREV0 GENMASK(2, 0)
#define BCOVE_ID_MAJREV0 GENMASK(5, 3)
#define BCOVE_ID_VENDID0 GENMASK(7, 6)
#define BCOVE_MINOR(x) (unsigned int)(((x) & BCOVE_ID_MINREV0) >> 0)
#define BCOVE_MAJOR(x) (unsigned int)(((x) & BCOVE_ID_MAJREV0) >> 3)
#define BCOVE_VENDOR(x) (unsigned int)(((x) & BCOVE_ID_VENDID0) >> 6)
#define BCOVE_IRQLVL1 0x01
#define BCOVE_PBIRQ 0x02
#define BCOVE_TMUIRQ 0x03
#define BCOVE_THRMIRQ 0x04
#define BCOVE_BCUIRQ 0x05
#define BCOVE_ADCIRQ 0x06
#define BCOVE_CHGRIRQ0 0x07
#define BCOVE_CHGRIRQ1 0x08
#define BCOVE_GPIOIRQ 0x09
#define BCOVE_CRITIRQ 0x0B
#define BCOVE_MIRQLVL1 0x0C
#define BCOVE_MPBIRQ 0x0D
#define BCOVE_MTMUIRQ 0x0E
#define BCOVE_MTHRMIRQ 0x0F
#define BCOVE_MBCUIRQ 0x10
#define BCOVE_MADCIRQ 0x11
#define BCOVE_MCHGRIRQ0 0x12
#define BCOVE_MCHGRIRQ1 0x13
#define BCOVE_MGPIOIRQ 0x14
#define BCOVE_MCRITIRQ 0x16
#define BCOVE_SCHGRIRQ0 0x4E
#define BCOVE_SCHGRIRQ1 0x4F
/* Level 1 IRQs */
#define BCOVE_LVL1_PWRBTN BIT(0) /* power button */
#define BCOVE_LVL1_TMU BIT(1) /* time management unit */
#define BCOVE_LVL1_THRM BIT(2) /* thermal */
#define BCOVE_LVL1_BCU BIT(3) /* burst control unit */
#define BCOVE_LVL1_ADC BIT(4) /* ADC */
#define BCOVE_LVL1_CHGR BIT(5) /* charger */
#define BCOVE_LVL1_GPIO BIT(6) /* GPIO */
#define BCOVE_LVL1_CRIT BIT(7) /* critical event */
/* Level 2 IRQs: power button */
#define BCOVE_PBIRQ_PBTN BIT(0)
#define BCOVE_PBIRQ_UBTN BIT(1)
/* Level 2 IRQs: ADC */
#define BCOVE_ADCIRQ_BATTEMP BIT(2)
#define BCOVE_ADCIRQ_SYSTEMP BIT(3)
#define BCOVE_ADCIRQ_BATTID BIT(4)
#define BCOVE_ADCIRQ_VIBATT BIT(5)
#define BCOVE_ADCIRQ_CCTICK BIT(7)
/* Level 2 IRQs: charger */
#define BCOVE_CHGRIRQ_BAT0ALRT BIT(4)
#define BCOVE_CHGRIRQ_BAT1ALRT BIT(5)
#define BCOVE_CHGRIRQ_BATCRIT BIT(6)
#define BCOVE_CHGRIRQ_VBUSDET BIT(0)
#define BCOVE_CHGRIRQ_DCDET BIT(1)
#define BCOVE_CHGRIRQ_BATTDET BIT(2)
#define BCOVE_CHGRIRQ_USBIDDET BIT(3)
#endif /* __INTEL_SOC_PMIC_MRFLD_H__ */

View File

@ -7,6 +7,14 @@
#ifndef __MFD_MT6397_CORE_H__
#define __MFD_MT6397_CORE_H__
#include <linux/mutex.h>
enum chip_id {
MT6323_CHIP_ID = 0x23,
MT6391_CHIP_ID = 0x91,
MT6397_CHIP_ID = 0x97,
};
enum mt6397_irq_numbers {
MT6397_IRQ_SPKL_AB = 0,
MT6397_IRQ_SPKR_AB,
@ -54,6 +62,9 @@ struct mt6397_chip {
u16 irq_masks_cache[2];
u16 int_con[2];
u16 int_status[2];
u16 chip_id;
};
int mt6397_irq_init(struct mt6397_chip *chip);
#endif /* __MFD_MT6397_CORE_H__ */

View File

@ -5513,6 +5513,18 @@ struct ec_params_fp_seed {
uint8_t seed[FP_CONTEXT_TPM_BYTES];
} __ec_align4;
#define EC_CMD_FP_ENC_STATUS 0x0409
/* FP TPM seed has been set or not */
#define FP_ENC_STATUS_SEED_SET BIT(0)
struct ec_response_fp_encryption_status {
/* Used bits in encryption engine status */
uint32_t valid_flags;
/* Encryption engine status */
uint32_t status;
} __ec_align4;
/*****************************************************************************/
/* Touchpad MCU commands: range 0x0500-0x05FF */