- New Drivers

- Add support for USART SPI to AT91*
 
  - New Functionality
    - Add support for Audio CODECs to motorola-cpcap
 
  - Fix-ups
    - DT documentation fix-ups; atmel-usart
    - Staticise functions/structs; spi-at91-usart, arizona-core
    - Constify; ti-lmu
    - Fix memory leaks; menelaus
    - Change device 'wake-up' status; ti_am335x_tscadc, max8997
    - Power Management (suspend/resume) semantic changes; ti_am335x_adc, cros_ec, max8997
    - SPDX churn; sec-core (+ headers), max* (+ headers), intel* (+ headers),
    - Trivial (whitespace, email addresses, alphabetisise); Kconfig, adp5520, intel_soc_pmic_*
    - Build as module; sec-irq
    - Use new %pOFn printk format for device_node.name; max77620
    - Remove unused code; madera
    - Use generic MACROs; intel_msic, intel_soc_pmic_crc
    - Move to GPIOD; ti-lmu
    - Use managed resources; ti-lmu
 
  - Bug Fixes
    - Add missing headers; at91-usart
    - Prevent device from entering low-power mode; arizona-core
    - Poll for BOOT_DONE to avoid still-booting NACK; madera-core
    - Prevent ADC read from shutting down device; mc13xxx-core
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAlvO94AACgkQUa+KL4f8
 d2GCaQ//XKJZ14EVT8gHVWekwUCJoqqLDDZH5Y+MDZkyq8ZnWZ3Iz2DeQ/g7KIAv
 EwtmWm4+TmfBMHziZSK3lZc/VBdhOWsFqi7/B1vQQ3n7RWHvhRcvFWASSzqCPpQP
 L7WbUtZWaeHx/26OKz1okbQbMuHEv11z8seXEX6axtSXlCbAF72fUaHDTAY0dCHD
 LAkomYee6wF3ohSwaPEH5FsgGRJ5ihnFmK8uGML+vBMq9IfrFOmOitrJmpOwPHud
 wKSEsKmVALeX/fP0kqcvaYOWTpNQecKEnJXH4uw0CC3QOIpL5nMmfKOjMfMF6wAq
 m76s5ZBt0UUMDZSiex+mzYQyfEXaP6bExtiUIfkXOii9uuaIIJ2J8rRLzoUrwpLy
 qTuGiIoUr3aoUFNx1uzmzeYVNLcQ2JeIrRw+MKlP60RiYDYyk8Ip96/ay+vLZXOl
 WTGFr9T5CnfjaHkoSgVcBu+F5q0v6qbvv0tBpjgYaRe9OClEEFqCSHqLo0oYwyeQ
 L4Y+tmGaDtUeRFdRyLp45X0y/DiThVkkDdOfRi3Fxn3PW4OxMOsU/GLCMQrbGXOr
 q5pJuSFjimu+JDZ2ibmMOtWrgtJ2EjTiBYLcDZNP2sujSWFE8azoEqGMXcQFDw/a
 Ltc6b474UNp9SGB4IC97f/B6EFUJ/TQWjo4WJXVEHdCRilRWBgM=
 =7B+Y
 -----END PGP SIGNATURE-----

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

Pull MFD updates from Lee Jones:
 "New Drivers
   - Add support for USART SPI to AT91*

  New Functionality
   - Add support for Audio CODECs to motorola-cpcap

  Fix-ups
   - DT documentation fix-ups; atmel-usart
   - Staticise functions/structs; spi-at91-usart, arizona-core
   - Constify; ti-lmu
   - Fix memory leaks; menelaus
   - Change device 'wake-up' status; ti_am335x_tscadc, max8997
   - Power Management (suspend/resume) semantic changes; ti_am335x_adc, cros_ec, max8997
   - SPDX churn; sec-core (+ headers), max* (+ headers), intel* (+ headers),
   - Trivial (whitespace, email addresses, alphabetisise); Kconfig, adp5520, intel_soc_pmic_*
   - Build as module; sec-irq
   - Use new %pOFn printk format for device_node.name; max77620
   - Remove unused code; madera
   - Use generic MACROs; intel_msic, intel_soc_pmic_crc
   - Move to GPIOD; ti-lmu
   - Use managed resources; ti-lmu

  Bug Fixes
   - Add missing headers; at91-usart
   - Prevent device from entering low-power mode; arizona-core
   - Poll for BOOT_DONE to avoid still-booting NACK; madera-core
   - Prevent ADC read from shutting down device; mc13xxx-core"

* tag 'mfd-next-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (45 commits)
  mfd: cros_ec: Avoid unneeded internal declaration warning
  mfd: ti-lmu: Use of_device_get_match_data() helper
  mfd: ti-lmu: Use managed resource for everything
  mfd: ti-lmu: Switch to GPIOD
  mfd: ti-lmu: constify mfd_cell tables
  mfd: max8997: Disable interrupt handling for suspend/resume cycle
  mfd: max8997: Enale irq-wakeup unconditionally
  mfd: arizona: Make array mclk_name static, shrinks object size
  MAINTAINERS: Add myself as designated reviewer of Intel MFD PMIC
  mfd: Convert Intel PMIC drivers to use SPDX identifier 1;5201;0c Reduce size of duplicated comments by switching to use SPDX identifier.
  mfd: Sort headers alphabetically for Intel PMIC drivers
  mfd: intel_soc_pmic_bxtwc: Chain power button IRQs as well
  mfd: intel_soc_pmic_crc: Use REGMAP_IRQ_REG() macro
  mfd: intel_soc_pmic_crc: Use DEFINE_RES_IRQ_NAMED() macro
  mfd: intel_msic: Use DEFINE_RES_IRQ() macro
  mfd: motorola-cpcap: Add audio-codec support
  mfd: mc13xxx-core: Fix PMIC shutdown when reading ADC values
  mfd: madera: Remove unused forward reference
  mfd: max77620: Convert to using %pOFn instead of device_node.name
  mfd: madera: Don't use regmap_read_poll_timeout to poll for BOOT_DONE
  ...
This commit is contained in:
Linus Torvalds 2018-10-25 06:19:15 -07:00
commit 3ea172c84d
72 changed files with 1045 additions and 733 deletions

View file

@ -99,6 +99,15 @@ config MFD_AAT2870_CORE
additional drivers must be enabled in order to use the
functionality of the device.
config MFD_AT91_USART
tristate "AT91 USART Driver"
select MFD_CORE
help
Select this to get support for AT91 USART IP. This is a wrapper
over at91-usart-serial driver and usart-spi-driver. Only one function
can be used at a time. The choice is done at boot time by the probe
function of this MFD driver according to a device tree property.
config MFD_ATMEL_FLEXCOM
tristate "Atmel Flexcom (Flexible Serial Communication Unit)"
select MFD_CORE
@ -1023,16 +1032,23 @@ config MFD_RN5T618
functionality of the device.
config MFD_SEC_CORE
bool "SAMSUNG Electronics PMIC Series Support"
tristate "SAMSUNG Electronics PMIC Series Support"
depends on I2C=y
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
help
Support for the Samsung Electronics MFD series.
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the functionality
of the device
Support for the Samsung Electronics PMIC devices coming
usually along with Samsung Exynos SoC chipset.
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the functionality
of the device
To compile this driver as a module, choose M here: the
module will be called sec-core.
Have in mind that important core drivers (like regulators) depend
on this driver so building this as a module might require proper
initial ramdisk or might not boot up as well in certain scenarios.
config MFD_SI476X_CORE
tristate "Silicon Laboratories 4761/64/68 AM/FM radio."

View file

@ -196,6 +196,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_TPS65090) += tps65090.o
obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
obj-$(CONFIG_MFD_AT91_USART) += at91-usart.o
obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o
obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o
obj-$(CONFIG_MFD_ATMEL_SMC) += atmel-smc.o

View file

@ -360,6 +360,6 @@ static struct i2c_driver adp5520_driver = {
module_i2c_driver(adp5520_driver);
MODULE_AUTHOR("Michael Hennerich <[email protected]>");
MODULE_AUTHOR("Michael Hennerich <[email protected]>");
MODULE_DESCRIPTION("ADP5520(01) PMIC-MFD Driver");
MODULE_LICENSE("GPL");

View file

@ -52,8 +52,10 @@ int arizona_clk32k_enable(struct arizona *arizona)
if (ret != 0)
goto err_ref;
ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]);
if (ret != 0)
goto err_pm;
if (ret != 0) {
pm_runtime_put_sync(arizona->dev);
goto err_ref;
}
break;
case ARIZONA_32KZ_MCLK2:
ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK2]);
@ -67,8 +69,6 @@ int arizona_clk32k_enable(struct arizona *arizona)
ARIZONA_CLK_32K_ENA);
}
err_pm:
pm_runtime_put_sync(arizona->dev);
err_ref:
if (ret != 0)
arizona->clk32k_ref--;
@ -990,7 +990,7 @@ static const struct mfd_cell wm8998_devs[] = {
int arizona_dev_init(struct arizona *arizona)
{
const char * const mclk_name[] = { "mclk1", "mclk2" };
static const char * const mclk_name[] = { "mclk1", "mclk2" };
struct device *dev = arizona->dev;
const char *type_name = NULL;
unsigned int reg, val;

72
drivers/mfd/at91-usart.c Normal file
View file

@ -0,0 +1,72 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Driver for AT91 USART
*
* Copyright (C) 2018 Microchip Technology
*
* Author: Radu Pirea <radu.pirea@microchip.com>
*
*/
#include <dt-bindings/mfd/at91-usart.h>
#include <linux/module.h>
#include <linux/mfd/core.h>
#include <linux/of.h>
#include <linux/property.h>
static struct mfd_cell at91_usart_spi_subdev = {
.name = "at91_usart_spi",
.of_compatible = "microchip,at91sam9g45-usart-spi",
};
static struct mfd_cell at91_usart_serial_subdev = {
.name = "atmel_usart_serial",
.of_compatible = "atmel,at91rm9200-usart-serial",
};
static int at91_usart_mode_probe(struct platform_device *pdev)
{
struct mfd_cell cell;
u32 opmode = AT91_USART_MODE_SERIAL;
device_property_read_u32(&pdev->dev, "atmel,usart-mode", &opmode);
switch (opmode) {
case AT91_USART_MODE_SPI:
cell = at91_usart_spi_subdev;
break;
case AT91_USART_MODE_SERIAL:
cell = at91_usart_serial_subdev;
break;
default:
dev_err(&pdev->dev, "atmel,usart-mode has an invalid value %u\n",
opmode);
return -EINVAL;
}
return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, &cell, 1,
NULL, 0, NULL);
}
static const struct of_device_id at91_usart_mode_of_match[] = {
{ .compatible = "atmel,at91rm9200-usart" },
{ .compatible = "atmel,at91sam9260-usart" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, at91_usart_mode_of_match);
static struct platform_driver at91_usart_mfd = {
.probe = at91_usart_mode_probe,
.driver = {
.name = "at91_usart_mode",
.of_match_table = at91_usart_mode_of_match,
},
};
module_platform_driver(at91_usart_mfd);
MODULE_AUTHOR("Radu Pirea <[email protected]>");
MODULE_DESCRIPTION("AT91 USART MFD driver");
MODULE_LICENSE("GPL v2");

View file

@ -218,7 +218,8 @@ EXPORT_SYMBOL(cros_ec_suspend);
static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev)
{
while (cros_ec_get_next_event(ec_dev, NULL) > 0)
while (ec_dev->mkbp_event_supported &&
cros_ec_get_next_event(ec_dev, NULL) > 0)
blocking_notifier_call_chain(&ec_dev->event_notifier,
1, ec_dev);
}

View file

@ -546,6 +546,7 @@ static struct platform_driver cros_ec_dev_driver = {
.name = DRV_NAME,
.pm = &cros_ec_dev_pm_ops,
},
.id_table = cros_ec_id,
.probe = ec_device_probe,
.remove = ec_device_remove,
.shutdown = ec_device_shutdown,

View file

@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Driver for Intel MSIC
*
* Copyright (C) 2011, Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/err.h>
@ -54,68 +51,44 @@ struct intel_msic {
};
static struct resource msic_touch_resources[] = {
{
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ(0),
};
static struct resource msic_adc_resources[] = {
{
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ(0),
};
static struct resource msic_battery_resources[] = {
{
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ(0),
};
static struct resource msic_gpio_resources[] = {
{
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ(0),
};
static struct resource msic_audio_resources[] = {
{
.name = "IRQ",
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ_NAMED(0, "IRQ"),
/*
* We will pass IRQ_BASE to the driver now but this can be removed
* when/if the driver starts to use intel_msic_irq_read().
*/
{
.name = "IRQ_BASE",
.flags = IORESOURCE_MEM,
.start = MSIC_IRQ_STATUS_ACCDET,
.end = MSIC_IRQ_STATUS_ACCDET,
},
DEFINE_RES_MEM_NAMED(MSIC_IRQ_STATUS_ACCDET, 1, "IRQ_BASE"),
};
static struct resource msic_hdmi_resources[] = {
{
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ(0),
};
static struct resource msic_thermal_resources[] = {
{
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ(0),
};
static struct resource msic_power_btn_resources[] = {
{
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ(0),
};
static struct resource msic_ocd_resources[] = {
{
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ(0),
};
/*

View file

@ -1,27 +1,20 @@
// SPDX-License-Identifier: GPL-2.0
/*
* MFD core driver for Intel Broxton Whiskey Cove PMIC
*
* Copyright (C) 2015 Intel Corporation. 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.
*/
#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/intel_soc_pmic.h>
#include <linux/mfd/intel_soc_pmic_bxtwc.h>
#include <linux/module.h>
#include <asm/intel_pmc_ipc.h>
/* PMIC device registers */
@ -31,8 +24,8 @@
/* Interrupt Status Registers */
#define BXTWC_IRQLVL1 0x4E02
#define BXTWC_PWRBTNIRQ 0x4E03
#define BXTWC_PWRBTNIRQ 0x4E03
#define BXTWC_THRM0IRQ 0x4E04
#define BXTWC_THRM1IRQ 0x4E05
#define BXTWC_THRM2IRQ 0x4E06
@ -47,10 +40,9 @@
/* Interrupt MASK Registers */
#define BXTWC_MIRQLVL1 0x4E0E
#define BXTWC_MPWRTNIRQ 0x4E0F
#define BXTWC_MIRQLVL1_MCHGR BIT(5)
#define BXTWC_MPWRBTNIRQ 0x4E0F
#define BXTWC_MTHRM0IRQ 0x4E12
#define BXTWC_MTHRM1IRQ 0x4E13
#define BXTWC_MTHRM2IRQ 0x4E14
@ -66,9 +58,7 @@
/* Whiskey Cove PMIC share same ACPI ID between different platforms */
#define BROXTON_PMIC_WC_HRV 4
/* Manage in two IRQ chips since mask registers are not consecutive */
enum bxtwc_irqs {
/* Level 1 */
BXTWC_PWRBTN_LVL1_IRQ = 0,
BXTWC_TMU_LVL1_IRQ,
BXTWC_THRM_LVL1_IRQ,
@ -77,9 +67,11 @@ enum bxtwc_irqs {
BXTWC_CHGR_LVL1_IRQ,
BXTWC_GPIO_LVL1_IRQ,
BXTWC_CRIT_LVL1_IRQ,
};
/* Level 2 */
BXTWC_PWRBTN_IRQ,
enum bxtwc_irqs_pwrbtn {
BXTWC_PWRBTN_IRQ = 0,
BXTWC_UIBTN_IRQ,
};
enum bxtwc_irqs_bcu {
@ -113,7 +105,10 @@ static const struct regmap_irq bxtwc_regmap_irqs[] = {
REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)),
REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)),
REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)),
REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03),
};
static const struct regmap_irq bxtwc_regmap_irqs_pwrbtn[] = {
REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, 0x01),
};
static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = {
@ -125,7 +120,7 @@ static const struct regmap_irq bxtwc_regmap_irqs_adc[] = {
};
static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = {
REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, BIT(5)),
REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, 0x20),
REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f),
REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f),
};
@ -144,7 +139,16 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
.mask_base = BXTWC_MIRQLVL1,
.irqs = bxtwc_regmap_irqs,
.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs),
.num_regs = 2,
.num_regs = 1,
};
static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = {
.name = "bxtwc_irq_chip_pwrbtn",
.status_base = BXTWC_PWRBTNIRQ,
.mask_base = BXTWC_MPWRBTNIRQ,
.irqs = bxtwc_regmap_irqs_pwrbtn,
.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_pwrbtn),
.num_regs = 1,
};
static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = {
@ -472,6 +476,16 @@ static int bxtwc_probe(struct platform_device *pdev)
return ret;
}
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
BXTWC_PWRBTN_LVL1_IRQ,
IRQF_ONESHOT,
&bxtwc_regmap_irq_chip_pwrbtn,
&pmic->irq_chip_data_pwrbtn);
if (ret) {
dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n");
return ret;
}
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
BXTWC_TMU_LVL1_IRQ,
IRQF_ONESHOT,

View file

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Device access for Dollar Cove TI PMIC
*
@ -6,10 +7,6 @@
*
* Cleanup and forward-ported
* Copyright (c) 2017 Takashi Iwai <tiwai@suse.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/acpi.h>

View file

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
/*
* MFD core driver for Intel Cherrytrail Whiskey Cove PMIC
*
@ -5,10 +6,6 @@
*
* Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
* Copyright (C) 2013-2015 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/acpi.h>

View file

@ -1,31 +1,24 @@
// SPDX-License-Identifier: GPL-2.0
/*
* intel_soc_pmic_core.c - Intel SoC PMIC MFD Driver
* Intel SoC PMIC MFD Driver
*
* Copyright (C) 2013, 2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that 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.
*
* Author: Yang, Bin <bin.yang@intel.com>
* Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
*/
#include <linux/module.h>
#include <linux/mfd/core.h>
#include <linux/acpi.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/gpio/consumer.h>
#include <linux/acpi.h>
#include <linux/regmap.h>
#include <linux/module.h>
#include <linux/mfd/core.h>
#include <linux/mfd/intel_soc_pmic.h>
#include <linux/gpio/machine.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
#include "intel_soc_pmic_core.h"
/* Crystal Cove PMIC shares same ACPI ID between different platforms */

View file

@ -1,17 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* intel_soc_pmic_core.h - Intel SoC PMIC MFD Driver
* Intel SoC PMIC MFD Driver
*
* Copyright (C) 2012-2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that 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.
*
* Author: Yang, Bin <bin.yang@intel.com>
* Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
*/

View file

@ -1,25 +1,18 @@
// SPDX-License-Identifier: GPL-2.0
/*
* intel_soc_pmic_crc.c - Device access for Crystal Cove PMIC
* Device access for Crystal Cove PMIC
*
* Copyright (C) 2013, 2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that 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.
*
* Author: Yang, Bin <bin.yang@intel.com>
* Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
*/
#include <linux/mfd/core.h>
#include <linux/interrupt.h>
#include <linux/regmap.h>
#include <linux/mfd/core.h>
#include <linux/mfd/intel_soc_pmic.h>
#include "intel_soc_pmic_core.h"
#define CRYSTAL_COVE_MAX_REGISTER 0xC6
@ -36,48 +29,23 @@
#define CRYSTAL_COVE_IRQ_VHDMIOCP 6
static struct resource gpio_resources[] = {
{
.name = "GPIO",
.start = CRYSTAL_COVE_IRQ_GPIO,
.end = CRYSTAL_COVE_IRQ_GPIO,
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_GPIO, "GPIO"),
};
static struct resource pwrsrc_resources[] = {
{
.name = "PWRSRC",
.start = CRYSTAL_COVE_IRQ_PWRSRC,
.end = CRYSTAL_COVE_IRQ_PWRSRC,
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_PWRSRC, "PWRSRC"),
};
static struct resource adc_resources[] = {
{
.name = "ADC",
.start = CRYSTAL_COVE_IRQ_ADC,
.end = CRYSTAL_COVE_IRQ_ADC,
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_ADC, "ADC"),
};
static struct resource thermal_resources[] = {
{
.name = "THERMAL",
.start = CRYSTAL_COVE_IRQ_THRM,
.end = CRYSTAL_COVE_IRQ_THRM,
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_THRM, "THERMAL"),
};
static struct resource bcu_resources[] = {
{
.name = "BCU",
.start = CRYSTAL_COVE_IRQ_BCU,
.end = CRYSTAL_COVE_IRQ_BCU,
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_BCU, "BCU"),
};
static struct mfd_cell crystal_cove_byt_dev[] = {
@ -134,27 +102,13 @@ static const struct regmap_config crystal_cove_regmap_config = {
};
static const struct regmap_irq crystal_cove_irqs[] = {
[CRYSTAL_COVE_IRQ_PWRSRC] = {
.mask = BIT(CRYSTAL_COVE_IRQ_PWRSRC),
},
[CRYSTAL_COVE_IRQ_THRM] = {
.mask = BIT(CRYSTAL_COVE_IRQ_THRM),
},
[CRYSTAL_COVE_IRQ_BCU] = {
.mask = BIT(CRYSTAL_COVE_IRQ_BCU),
},
[CRYSTAL_COVE_IRQ_ADC] = {
.mask = BIT(CRYSTAL_COVE_IRQ_ADC),
},
[CRYSTAL_COVE_IRQ_CHGR] = {
.mask = BIT(CRYSTAL_COVE_IRQ_CHGR),
},
[CRYSTAL_COVE_IRQ_GPIO] = {
.mask = BIT(CRYSTAL_COVE_IRQ_GPIO),
},
[CRYSTAL_COVE_IRQ_VHDMIOCP] = {
.mask = BIT(CRYSTAL_COVE_IRQ_VHDMIOCP),
},
REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_PWRSRC, 0, BIT(CRYSTAL_COVE_IRQ_PWRSRC)),
REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_THRM, 0, BIT(CRYSTAL_COVE_IRQ_THRM)),
REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_BCU, 0, BIT(CRYSTAL_COVE_IRQ_BCU)),
REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_ADC, 0, BIT(CRYSTAL_COVE_IRQ_ADC)),
REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_CHGR, 0, BIT(CRYSTAL_COVE_IRQ_CHGR)),
REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_GPIO, 0, BIT(CRYSTAL_COVE_IRQ_GPIO)),
REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_VHDMIOCP, 0, BIT(CRYSTAL_COVE_IRQ_VHDMIOCP)),
};
static const struct regmap_irq_chip crystal_cove_irq_chip = {

View file

@ -132,32 +132,39 @@ const char *madera_name_from_type(enum madera_type type)
}
EXPORT_SYMBOL_GPL(madera_name_from_type);
#define MADERA_BOOT_POLL_MAX_INTERVAL_US 5000
#define MADERA_BOOT_POLL_TIMEOUT_US 25000
#define MADERA_BOOT_POLL_INTERVAL_USEC 5000
#define MADERA_BOOT_POLL_TIMEOUT_USEC 25000
static int madera_wait_for_boot(struct madera *madera)
{
ktime_t timeout;
unsigned int val;
int ret;
int ret = 0;
/*
* We can't use an interrupt as we need to runtime resume to do so,
* so we poll the status bit. This won't race with the interrupt
* handler because it will be blocked on runtime resume.
* The chip could NAK a read request while it is booting so ignore
* errors from regmap_read.
*/
ret = regmap_read_poll_timeout(madera->regmap,
MADERA_IRQ1_RAW_STATUS_1,
val,
(val & MADERA_BOOT_DONE_STS1),
MADERA_BOOT_POLL_MAX_INTERVAL_US,
MADERA_BOOT_POLL_TIMEOUT_US);
timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC);
regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
while (!(val & MADERA_BOOT_DONE_STS1) &&
!ktime_after(ktime_get(), timeout)) {
usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2,
MADERA_BOOT_POLL_INTERVAL_USEC);
regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
};
if (ret)
dev_err(madera->dev, "Polling BOOT_DONE_STS failed: %d\n", ret);
if (!(val & MADERA_BOOT_DONE_STS1)) {
dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n");
ret = -ETIMEDOUT;
}
/*
* BOOT_DONE defaults to unmasked on boot so we must ack it.
* Do this unconditionally to avoid interrupt storms.
* Do this even after a timeout to avoid interrupt storms.
*/
regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
MADERA_BOOT_DONE_EINT1);

View file

@ -1,22 +1,12 @@
/*
* max14577.c - mfd core driver for the Maxim 14577/77836
*
* Copyright (C) 2014 Samsung Electronics
* Chanwoo Choi <cw00.choi@samsung.com>
* Krzysztof Kozlowski <krzk@kernel.org>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that 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.
*
* This driver is based on max8997.c
*/
// SPDX-License-Identifier: GPL-2.0+
//
// max14577.c - mfd core driver for the Maxim 14577/77836
//
// Copyright (C) 2014 Samsung Electronics
// Chanwoo Choi <[email protected]>
// Krzysztof Kozlowski <[email protected]>
//
// This driver is based on max8997.c
#include <linux/err.h>
#include <linux/module.h>

View file

@ -285,7 +285,7 @@ static int max77620_config_fps(struct max77620_chip *chip,
}
if (fps_id == MAX77620_FPS_COUNT) {
dev_err(dev, "FPS node name %s is not valid\n", fps_np->name);
dev_err(dev, "FPS node name %pOFn is not valid\n", fps_np);
return -EINVAL;
}

View file

@ -1,26 +1,12 @@
/*
* max77686.c - mfd core driver for the Maxim 77686/802
*
* Copyright (C) 2012 Samsung Electronics
* Chiwoong Byun <woong.byun@samsung.com>
* Jonghwa Lee <jonghwa3.lee@samsung.com>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This driver is based on max8997.c
*/
// SPDX-License-Identifier: GPL-2.0+
//
// max77686.c - mfd core driver for the Maxim 77686/802
//
// Copyright (C) 2012 Samsung Electronics
// Chiwoong Byun <[email protected]>
// Jonghwa Lee <[email protected]>
//
//This driver is based on max8997.c
#include <linux/export.h>
#include <linux/slab.h>

View file

@ -1,27 +1,13 @@
/*
* max77693.c - mfd core driver for the MAX 77693
*
* Copyright (C) 2012 Samsung Electronics
* SangYoung Son <hello.son@samsung.com>
*
* This program is not provided / owned by Maxim Integrated Products.
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This driver is based on max8997.c
*/
// SPDX-License-Identifier: GPL-2.0+
//
// max77693.c - mfd core driver for the MAX 77693
//
// Copyright (C) 2012 Samsung Electronics
// SangYoung Son <[email protected]>
//
// This program is not provided / owned by Maxim Integrated Products.
//
// This driver is based on max8997.c
#include <linux/module.h>
#include <linux/slab.h>

View file

@ -1,15 +1,10 @@
/*
* MFD core driver for the Maxim MAX77843
*
* Copyright (C) 2015 Samsung Electronics
* Author: Jaewon Kim <jaewon02.kim@samsung.com>
* Author: Beomho Seo <beomho.seo@samsung.com>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
// SPDX-License-Identifier: GPL-2.0+
//
// MFD core driver for the Maxim MAX77843
//
// Copyright (C) 2015 Samsung Electronics
// Author: Jaewon Kim <[email protected]>
// Author: Beomho Seo <[email protected]>
#include <linux/err.h>
#include <linux/i2c.h>

View file

@ -1,25 +1,11 @@
/*
* max8997-irq.c - Interrupt controller support for MAX8997
*
* Copyright (C) 2011 Samsung Electronics Co.Ltd
* MyungJoo Ham <myungjoo.ham@samsung.com>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This driver is based on max8998-irq.c
*/
// SPDX-License-Identifier: GPL-2.0+
//
// max8997-irq.c - Interrupt controller support for MAX8997
//
// Copyright (C) 2011 Samsung Electronics Co.Ltd
// MyungJoo Ham <[email protected]>
//
// This driver is based on max8998-irq.c
#include <linux/err.h>
#include <linux/irq.h>

View file

@ -1,25 +1,11 @@
/*
* max8997.c - mfd core driver for the Maxim 8966 and 8997
*
* Copyright (C) 2011 Samsung Electronics
* MyungJoo Ham <myungjoo.ham@samsung.com>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This driver is based on max8998.c
*/
// SPDX-License-Identifier: GPL-2.0+
//
// max8997.c - mfd core driver for the Maxim 8966 and 8997
//
// Copyright (C) 2011 Samsung Electronics
// MyungJoo Ham <[email protected]>
//
// This driver is based on max8998.c
#include <linux/err.h>
#include <linux/slab.h>
@ -153,12 +139,6 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
pd->ono = irq_of_parse_and_map(dev->of_node, 1);
/*
* ToDo: the 'wakeup' member in the platform data is more of a linux
* specfic information. Hence, there is no binding for that yet and
* not parsed here.
*/
return pd;
}
@ -246,7 +226,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
*/
/* MAX8997 has a power button input. */
device_init_wakeup(max8997->dev, pdata->wakeup);
device_init_wakeup(max8997->dev, true);
return ret;
@ -468,6 +448,7 @@ static int max8997_suspend(struct device *dev)
struct i2c_client *i2c = to_i2c_client(dev);
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
disable_irq(max8997->irq);
if (device_may_wakeup(dev))
irq_set_irq_wake(max8997->irq, 1);
return 0;
@ -480,6 +461,7 @@ static int max8997_resume(struct device *dev)
if (device_may_wakeup(dev))
irq_set_irq_wake(max8997->irq, 0);
enable_irq(max8997->irq);
return max8997_irq_resume(max8997);
}

View file

@ -1,15 +1,9 @@
/*
* Interrupt controller support for MAX8998
*
* Copyright (C) 2010 Samsung Electronics Co.Ltd
* Author: Joonyoung Shim <jy0922.shim@samsung.com>
*
* 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 the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
// SPDX-License-Identifier: GPL-2.0+
//
// Interrupt controller support for MAX8998
//
// Copyright (C) 2010 Samsung Electronics Co.Ltd
// Author: Joonyoung Shim <[email protected]>
#include <linux/device.h>
#include <linux/interrupt.h>

View file

@ -1,24 +1,10 @@
/*
* max8998.c - mfd core driver for the Maxim 8998
*
* Copyright (C) 2009-2010 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
* Marek Szyprowski <m.szyprowski@samsung.com>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// SPDX-License-Identifier: GPL-2.0+
//
// max8998.c - mfd core driver for the Maxim 8998
//
// Copyright (C) 2009-2010 Samsung Electronics
// Kyungmin Park <[email protected]>
// Marek Szyprowski <[email protected]>
#include <linux/err.h>
#include <linux/init.h>

View file

@ -276,7 +276,8 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
mc13xxx_reg_read(mc13xxx, MC13XXX_ADC0, &old_adc0);
adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2;
adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2 |
MC13XXX_ADC0_CHRGRAWDIV;
adc1 = MC13XXX_ADC1_ADEN | MC13XXX_ADC1_ADTRIGIGN | MC13XXX_ADC1_ASC;
/*

View file

@ -1094,6 +1094,7 @@ static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
static inline void menelaus_rtc_init(struct menelaus_chip *m)
{
int alarm = (m->client->irq > 0);
int err;
/* assume 32KDETEN pin is pulled high */
if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) {
@ -1101,6 +1102,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
return;
}
m->rtc = devm_rtc_allocate_device(&m->client->dev);
if (IS_ERR(m->rtc))
return;
m->rtc->ops = &menelaus_rtc_ops;
/* support RTC alarm; it can issue wakeups */
if (alarm) {
if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
@ -1125,10 +1132,8 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control);
}
m->rtc = rtc_device_register(DRIVER_NAME,
&m->client->dev,
&menelaus_rtc_ops, THIS_MODULE);
if (IS_ERR(m->rtc)) {
err = rtc_register_device(m->rtc);
if (err) {
if (alarm) {
menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ);
device_init_wakeup(&m->client->dev, 0);

View file

@ -18,6 +18,7 @@
#include <linux/regmap.h>
#include <linux/sysfs.h>
#include <linux/mfd/core.h>
#include <linux/mfd/motorola-cpcap.h>
#include <linux/spi/spi.h>
@ -216,6 +217,53 @@ static const struct regmap_config cpcap_regmap_config = {
.val_format_endian = REGMAP_ENDIAN_LITTLE,
};
static const struct mfd_cell cpcap_mfd_devices[] = {
{
.name = "cpcap_adc",
.of_compatible = "motorola,mapphone-cpcap-adc",
}, {
.name = "cpcap_battery",
.of_compatible = "motorola,cpcap-battery",
}, {
.name = "cpcap-charger",
.of_compatible = "motorola,mapphone-cpcap-charger",
}, {
.name = "cpcap-regulator",
.of_compatible = "motorola,mapphone-cpcap-regulator",
}, {
.name = "cpcap-rtc",
.of_compatible = "motorola,cpcap-rtc",
}, {
.name = "cpcap-pwrbutton",
.of_compatible = "motorola,cpcap-pwrbutton",
}, {
.name = "cpcap-usb-phy",
.of_compatible = "motorola,mapphone-cpcap-usb-phy",
}, {
.name = "cpcap-led",
.id = 0,
.of_compatible = "motorola,cpcap-led-red",
}, {
.name = "cpcap-led",
.id = 1,
.of_compatible = "motorola,cpcap-led-green",
}, {
.name = "cpcap-led",
.id = 2,
.of_compatible = "motorola,cpcap-led-blue",
}, {
.name = "cpcap-led",
.id = 3,
.of_compatible = "motorola,cpcap-led-adl",
}, {
.name = "cpcap-led",
.id = 4,
.of_compatible = "motorola,cpcap-led-cp",
}, {
.name = "cpcap-codec",
}
};
static int cpcap_probe(struct spi_device *spi)
{
const struct of_device_id *match;
@ -260,7 +308,8 @@ static int cpcap_probe(struct spi_device *spi)
if (ret)
return ret;
return devm_of_platform_populate(&cpcap->spi->dev);
return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices,
ARRAY_SIZE(cpcap_mfd_devices), NULL, 0, NULL);
}
static struct spi_driver cpcap_driver = {

View file

@ -1,15 +1,7 @@
/*
* sec-core.c
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd
* http://www.samsung.com
*
* 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 the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (c) 2012 Samsung Electronics Co., Ltd
// http://www.samsung.com
#include <linux/module.h>
#include <linux/moduleparam.h>

View file

@ -1,19 +1,12 @@
/*
* sec-irq.c
*
* Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
* http://www.samsung.com
*
* 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 the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
// http://www.samsung.com
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/mfd/samsung/core.h>
@ -501,3 +494,10 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
return 0;
}
EXPORT_SYMBOL_GPL(sec_irq_init);
MODULE_AUTHOR("Sangbeom Kim <[email protected]>");
MODULE_AUTHOR("Chanwoo Choi <[email protected]>");
MODULE_AUTHOR("Krzysztof Kozlowski <[email protected]>");
MODULE_DESCRIPTION("Interrupt support for the S5M MFD");
MODULE_LICENSE("GPL");

View file

@ -12,7 +12,7 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
@ -21,28 +21,18 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
struct ti_lmu_data {
struct mfd_cell *cells;
const struct mfd_cell *cells;
int num_cells;
unsigned int max_register;
};
static int ti_lmu_enable_hw(struct ti_lmu *lmu, enum ti_lmu_id id)
{
int ret;
if (gpio_is_valid(lmu->en_gpio)) {
ret = devm_gpio_request_one(lmu->dev, lmu->en_gpio,
GPIOF_OUT_INIT_HIGH, "lmu_hwen");
if (ret) {
dev_err(lmu->dev, "Can not request enable GPIO: %d\n",
ret);
return ret;
}
}
if (lmu->en_gpio)
gpiod_set_value(lmu->en_gpio, 1);
/* Delay about 1ms after HW enable pin control */
usleep_range(1000, 1500);
@ -57,13 +47,14 @@ static int ti_lmu_enable_hw(struct ti_lmu *lmu, enum ti_lmu_id id)
return 0;
}
static void ti_lmu_disable_hw(struct ti_lmu *lmu)
static void ti_lmu_disable_hw(void *data)
{
if (gpio_is_valid(lmu->en_gpio))
gpio_set_value(lmu->en_gpio, 0);
struct ti_lmu *lmu = data;
if (lmu->en_gpio)
gpiod_set_value(lmu->en_gpio, 0);
}
static struct mfd_cell lm3532_devices[] = {
static const struct mfd_cell lm3532_devices[] = {
{
.name = "ti-lmu-backlight",
.id = LM3532,
@ -78,7 +69,7 @@ static struct mfd_cell lm3532_devices[] = {
.of_compatible = "ti,lm363x-regulator", \
} \
static struct mfd_cell lm3631_devices[] = {
static const struct mfd_cell lm3631_devices[] = {
LM363X_REGULATOR(LM3631_BOOST),
LM363X_REGULATOR(LM3631_LDO_CONT),
LM363X_REGULATOR(LM3631_LDO_OREF),
@ -91,7 +82,7 @@ static struct mfd_cell lm3631_devices[] = {
},
};
static struct mfd_cell lm3632_devices[] = {
static const struct mfd_cell lm3632_devices[] = {
LM363X_REGULATOR(LM3632_BOOST),
LM363X_REGULATOR(LM3632_LDO_POS),
LM363X_REGULATOR(LM3632_LDO_NEG),
@ -102,7 +93,7 @@ static struct mfd_cell lm3632_devices[] = {
},
};
static struct mfd_cell lm3633_devices[] = {
static const struct mfd_cell lm3633_devices[] = {
{
.name = "ti-lmu-backlight",
.id = LM3633,
@ -120,7 +111,7 @@ static struct mfd_cell lm3633_devices[] = {
},
};
static struct mfd_cell lm3695_devices[] = {
static const struct mfd_cell lm3695_devices[] = {
{
.name = "ti-lmu-backlight",
.id = LM3695,
@ -128,7 +119,7 @@ static struct mfd_cell lm3695_devices[] = {
},
};
static struct mfd_cell lm3697_devices[] = {
static const struct mfd_cell lm3697_devices[] = {
{
.name = "ti-lmu-backlight",
.id = LM3697,
@ -157,34 +148,21 @@ TI_LMU_DATA(lm3633, LM3633_MAX_REG);
TI_LMU_DATA(lm3695, LM3695_MAX_REG);
TI_LMU_DATA(lm3697, LM3697_MAX_REG);
static const struct of_device_id ti_lmu_of_match[] = {
{ .compatible = "ti,lm3532", .data = &lm3532_data },
{ .compatible = "ti,lm3631", .data = &lm3631_data },
{ .compatible = "ti,lm3632", .data = &lm3632_data },
{ .compatible = "ti,lm3633", .data = &lm3633_data },
{ .compatible = "ti,lm3695", .data = &lm3695_data },
{ .compatible = "ti,lm3697", .data = &lm3697_data },
{ }
};
MODULE_DEVICE_TABLE(of, ti_lmu_of_match);
static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct device *dev = &cl->dev;
const struct of_device_id *match;
const struct ti_lmu_data *data;
struct regmap_config regmap_cfg;
struct ti_lmu *lmu;
int ret;
match = of_match_device(ti_lmu_of_match, dev);
if (!match)
return -ENODEV;
/*
* Get device specific data from of_match table.
* This data is defined by using TI_LMU_DATA() macro.
*/
data = (struct ti_lmu_data *)match->data;
data = of_device_get_match_data(dev);
if (!data)
return -ENODEV;
lmu = devm_kzalloc(dev, sizeof(*lmu), GFP_KERNEL);
if (!lmu)
@ -204,11 +182,21 @@ static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id)
return PTR_ERR(lmu->regmap);
/* HW enable pin control and additional power up sequence if required */
lmu->en_gpio = of_get_named_gpio(dev->of_node, "enable-gpios", 0);
lmu->en_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
if (IS_ERR(lmu->en_gpio)) {
ret = PTR_ERR(lmu->en_gpio);
dev_err(dev, "Can not request enable GPIO: %d\n", ret);
return ret;
}
ret = ti_lmu_enable_hw(lmu, id->driver_data);
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, ti_lmu_disable_hw, lmu);
if (ret)
return ret;
/*
* Fault circuit(open/short) can be detected by ti-lmu-fault-monitor.
* After fault detection is done, some devices should re-initialize
@ -218,18 +206,20 @@ static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id)
i2c_set_clientdata(cl, lmu);
return mfd_add_devices(lmu->dev, 0, data->cells,
data->num_cells, NULL, 0, NULL);
return devm_mfd_add_devices(lmu->dev, 0, data->cells,
data->num_cells, NULL, 0, NULL);
}
static int ti_lmu_remove(struct i2c_client *cl)
{
struct ti_lmu *lmu = i2c_get_clientdata(cl);
ti_lmu_disable_hw(lmu);
mfd_remove_devices(lmu->dev);
return 0;
}
static const struct of_device_id ti_lmu_of_match[] = {
{ .compatible = "ti,lm3532", .data = &lm3532_data },
{ .compatible = "ti,lm3631", .data = &lm3631_data },
{ .compatible = "ti,lm3632", .data = &lm3632_data },
{ .compatible = "ti,lm3633", .data = &lm3633_data },
{ .compatible = "ti,lm3695", .data = &lm3695_data },
{ .compatible = "ti,lm3697", .data = &lm3697_data },
{ }
};
MODULE_DEVICE_TABLE(of, ti_lmu_of_match);
static const struct i2c_device_id ti_lmu_ids[] = {
{ "lm3532", LM3532 },
@ -244,7 +234,6 @@ MODULE_DEVICE_TABLE(i2c, ti_lmu_ids);
static struct i2c_driver ti_lmu_driver = {
.probe = ti_lmu_probe,
.remove = ti_lmu_remove,
.driver = {
.name = "ti-lmu",
.of_match_table = ti_lmu_of_match,

View file

@ -269,7 +269,6 @@ static int ti_tscadc_probe(struct platform_device *pdev)
if (err < 0)
goto err_disable_clk;
device_init_wakeup(&pdev->dev, true);
platform_set_drvdata(pdev, tscadc);
return 0;
@ -294,11 +293,24 @@ static int ti_tscadc_remove(struct platform_device *pdev)
return 0;
}
static int __maybe_unused ti_tscadc_can_wakeup(struct device *dev, void *data)
{
return device_may_wakeup(dev);
}
static int __maybe_unused tscadc_suspend(struct device *dev)
{
struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev);
regmap_write(tscadc->regmap, REG_SE, 0x00);
if (device_for_each_child(dev, NULL, ti_tscadc_can_wakeup)) {
u32 ctrl;
regmap_read(tscadc->regmap, REG_CTRL, &ctrl);
ctrl &= ~(CNTRLREG_POWERDOWN);
ctrl |= CNTRLREG_TSCSSENB;
regmap_write(tscadc->regmap, REG_CTRL, ctrl);
}
pm_runtime_put_sync(dev);
return 0;