Commit e5744abb authored by Linus Torvalds's avatar Linus Torvalds

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

Pull MFD updates from Lee Jones:
 "Changes to existing drivers:
   - Use of managed resources - omap, twl4030, ti_am335x_tscadc
   - Advanced error handling - omap
   - Rework clk management - omap
   - Device Tree (re-)work - tc3589x, pm8921, da9055, sec
   - IRC management overhaul and !BROKEN - pm8921
   - Convert to regmap - ssbi, pm8921
   - Use simple power-management ops - ucb1x00
   - Include file clean-up - adp5520, cs5535, janz, lpc_ich,
      - lpc_sch, max14577, mcp-sa11x0, pcf50633-adc, rc5t583,
      	rdc321x-southbridge, retu, smsc-ece1099, ti-ssp, ti_am335x_tscadc,
	tps65912, vexpress-config, wm8350, ywm8350
   - Various bug fixes across the subsystem
      - NULL/invalid pointer dereference prevention
      - Resource leak mitigation,
      - Variable used initialised
      - Staticise various containers
      - Enforce return value checks

  New drivers/supported devices:
   - Add support for s2mps14 and s2mpa01 to sec
   - Add support for da9063 (v5) to da9063
   - Add support for atom-c2000 to gpio-ich
   - Add support for come-{mbt10,cbt6,chl6} to kempld
   - Add support for da9053 to da9052
   - Add support for itco-wdt (v3) and baytrail to lpc_ich
   - Add new drivers for tps65218, rtsx_usb, bcm590xx

  (Re-)moved drivers:
   - twl4030 ==> drivers/iio
   - ti-ssp  ==> /dev/null"

* tag 'mfd-for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (103 commits)
  mfd: wm5110: Correct default for HEADPHONE_DETECT_1
  mfd: arizona: Correct small errors in the DT binding documentation
  mfd: arizona: Mark DSP clocking register as volatile
  mfd: devicetree: bindings: Add pm8xxx RTC description
  mfd: kempld-core: Fix potential hang-up during boot
  mfd: sec-core: Fix uninitialized 'regmap_rtc' on S2MPA01
  mfd: tps65910: Fix regmap_irq_chip_data leak on mfd_add_devices fail
  mfd: tps65910: Fix possible invalid pointer dereference on regmap_add_irq_chip fail
  mfd: sec-core: Fix I2C dummy device resource leak on probe failure
  mfd: sec-core: Add of_compatible strings for clock MFD cells
  mfd: Remove obsolete ti-ssp driver
  Documentation: mfd: s2mps11: Describe S5M8767 and S2MPS14 clocks
  mfd: bcm590xx: Fix type argument for module device table
  mfd: lpc_ich: Add support for Intel Bay Trail SoC
  mfd: lpc_ich: Add support for NM10 GPIO
  mfd: lpc_ich: Change Avoton to iTCO v3
  watchdog: iTCO_wdt: Add support for v3 silicon
  mfd: lpc_ich: Add support for iTCO v3
  mfd: lpc_ich: Remove lpc_ich_cfg struct use
  mfd: lpc_ich: Only configure watchdog or GPIO when present
  ...
parents c29aa153 2d28ca73
* TWL4030 Monitoring Analog to Digital Converter (MADC)
The MADC subsystem in the TWL4030 consists of a 10-bit ADC
combined with a 16-input analog multiplexer.
Required properties:
- compatible: Should contain "ti,twl4030-madc".
- interrupts: IRQ line for the MADC submodule.
- #io-channel-cells: Should be set to <1>.
Optional properties:
- ti,system-uses-second-madc-irq: boolean, set if the second madc irq register
should be used, which is intended to be used
by Co-Processors (e.g. a modem).
Example:
&twl {
madc {
compatible = "ti,twl4030-madc";
interrupts = <3>;
#io-channel-cells = <1>;
};
};
......@@ -5,9 +5,10 @@ of analogue I/O.
Required properties:
- compatible : one of the following chip-specific strings:
"wlf,wm5102"
"wlf,wm5110"
- compatible : One of the following chip-specific strings:
"wlf,wm5102"
"wlf,wm5110"
"wlf,wm8997"
- reg : I2C slave address when connected using I2C, chip select number when
using SPI.
......@@ -25,8 +26,9 @@ Required properties:
- #gpio-cells : Must be 2. The first cell is the pin number and the
second cell is used to specify optional parameters (currently unused).
- AVDD1-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
SPKVDDL-supply, SPKVDDR-supply : power supplies for the device, as covered
- AVDD-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply (wm5102, wm5110),
CPVDD-supply, SPKVDDL-supply (wm5102, wm5110), SPKVDDR-supply (wm5102,
wm5110), SPKVDD-supply (wm8997) : Power supplies for the device, as covered
in Documentation/devicetree/bindings/regulator/regulator.txt
Optional properties:
......@@ -46,6 +48,7 @@ codec: wm5102@1a {
compatible = "wlf,wm5102";
reg = <0x1a>;
interrupts = <347>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&gic>;
......@@ -53,10 +56,10 @@ codec: wm5102@1a {
#gpio-cells = <2>;
wlf,gpio-defaults = <
0x00000000, /* AIF1TXLRCLK */
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0x00000000 /* AIF1TXLRCLK */
0xffffffff
0xffffffff
0xffffffff
0xffffffff
>;
};
-------------------------------
BCM590xx Power Management Units
-------------------------------
Required properties:
- compatible: "brcm,bcm59056"
- reg: I2C slave address
- interrupts: interrupt for the PMU. Generic interrupt client node bindings
are described in interrupt-controller/interrupts.txt
------------------
Voltage Regulators
------------------
Optional child nodes:
- regulators: container node for regulators following the generic
regulator binding in regulator/regulator.txt
The valid regulator node names for BCM59056 are:
rfldo, camldo1, camldo2, simldo1, simldo2, sdldo, sdxldo,
mmcldo1, mmcldo2, audldo, micldo, usbldo, vibldo,
csr, iosr1, iosr2, msr, sdsr1, sdsr2, vsr
Example:
pmu: bcm59056@8 {
compatible = "brcm,bcm59056";
reg = <0x08>;
interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
regulators {
rfldo_reg: rfldo {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
};
...
};
};
* Dialog DA9055 Power Management Integrated Circuit (PMIC)
DA9055 consists of a large and varied group of sub-devices (I2C Only):
Device Supply Names Description
------ ------------ -----------
da9055-gpio : : GPIOs
da9055-regulator : : Regulators
da9055-onkey : : On key
da9055-rtc : : RTC
da9055-hwmon : : ADC
da9055-watchdog : : Watchdog
The CODEC device in DA9055 has a separate, configurable I2C address and so
is instantiated separately from the PMIC.
For details on accompanying CODEC I2C device, see the following:
Documentation/devicetree/bindings/sound/da9055.txt
======
Required properties:
- compatible : Should be "dlg,da9055-pmic"
- reg: Specifies the I2C slave address (defaults to 0x5a but can be modified)
- interrupt-parent: Specifies the phandle of the interrupt controller to which
the IRQs from da9055 are delivered to.
- interrupts: IRQ line info for da9055 chip.
- interrupt-controller: da9055 has internal IRQs (has own IRQ domain).
- #interrupt-cells: Should be 1, is the local IRQ number for da9055.
Sub-nodes:
- regulators : Contain the regulator nodes. The DA9055 regulators are
bound using their names as listed below:
buck1 : regulator BUCK1
buck2 : regulator BUCK2
ldo1 : regulator LDO1
ldo2 : regulator LDO2
ldo3 : regulator LDO3
ldo4 : regulator LDO4
ldo5 : regulator LDO5
ldo6 : regulator LDO6
The bindings details of individual regulator device can be found in:
Documentation/devicetree/bindings/regulator/regulator.txt
Example:
pmic: da9055-pmic@5a {
compatible = "dlg,da9055-pmic";
reg = <0x5a>;
interrupt-parent = <&intc>;
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
regulators {
buck1: BUCK1 {
regulator-min-microvolt = <725000>;
regulator-max-microvolt = <2075000>;
};
buck2: BUCK2 {
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <2500000>;
};
ldo1: LDO1 {
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <3300000>;
};
};
};
......@@ -32,6 +32,29 @@ Optional properties:
- single-ulpi-bypass: Must be present if the controller contains a single
ULPI bypass control bit. e.g. OMAP3 silicon <= ES2.1
- clocks: a list of phandles and clock-specifier pairs, one for each entry in
clock-names.
- clock-names: should include:
For OMAP3
* "usbhost_120m_fck" - 120MHz Functional clock.
For OMAP4+
* "refclk_60m_int" - 60MHz internal reference clock for UTMI clock mux
* "refclk_60m_ext_p1" - 60MHz external ref. clock for Port 1's UTMI clock mux.
* "refclk_60m_ext_p2" - 60MHz external ref. clock for Port 2's UTMI clock mux
* "utmi_p1_gfclk" - Port 1 UTMI clock mux.
* "utmi_p2_gfclk" - Port 2 UTMI clock mux.
* "usb_host_hs_utmi_p1_clk" - Port 1 UTMI clock gate.
* "usb_host_hs_utmi_p2_clk" - Port 2 UTMI clock gate.
* "usb_host_hs_utmi_p3_clk" - Port 3 UTMI clock gate.
* "usb_host_hs_hsic480m_p1_clk" - Port 1 480MHz HSIC clock gate.
* "usb_host_hs_hsic480m_p2_clk" - Port 2 480MHz HSIC clock gate.
* "usb_host_hs_hsic480m_p3_clk" - Port 3 480MHz HSIC clock gate.
* "usb_host_hs_hsic60m_p1_clk" - Port 1 60MHz HSIC clock gate.
* "usb_host_hs_hsic60m_p2_clk" - Port 2 60MHz HSIC clock gate.
* "usb_host_hs_hsic60m_p3_clk" - Port 3 60MHz HSIC clock gate.
Required properties if child node exists:
- #address-cells: Must be 1
......
......@@ -7,6 +7,16 @@ Required properties:
- interrupts : should contain the TLL module's interrupt
- ti,hwmod : must contain "usb_tll_hs"
Optional properties:
- clocks: a list of phandles and clock-specifier pairs, one for each entry in
clock-names.
- clock-names: should include:
* "usb_tll_hs_usb_ch0_clk" - USB TLL channel 0 clock
* "usb_tll_hs_usb_ch1_clk" - USB TLL channel 1 clock
* "usb_tll_hs_usb_ch2_clk" - USB TLL channel 2 clock
Example:
usbhstll: usbhstll@4a062000 {
......
Qualcomm PM8xxx PMIC multi-function devices
The PM8xxx family of Power Management ICs are used to provide regulated
voltages and other various functionality to Qualcomm SoCs.
= PROPERTIES
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,pm8058"
"qcom,pm8921"
- #address-cells:
Usage: required
Value type: <u32>
Definition: must be 1
- #size-cells:
Usage: required
Value type: <u32>
Definition: must be 0
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: specifies the interrupt that indicates a subdevice
has generated an interrupt (summary interrupt). The
format of the specifier is defined by the binding document
describing the node's interrupt parent.
- #interrupt-cells:
Usage: required
Value type : <u32>
Definition: must be 2. Specifies the number of cells needed to encode
an interrupt source. The 1st cell contains the interrupt
number. The 2nd cell is the trigger type and level flags
encoded as follows:
1 = low-to-high edge triggered
2 = high-to-low edge triggered
4 = active high level-sensitive
8 = active low level-sensitive
- interrupt-controller:
Usage: required
Value type: <empty>
Definition: identifies this node as an interrupt controller
= SUBCOMPONENTS
The PMIC contains multiple independent functions, each described in a subnode.
The below bindings specify the set of valid subnodes.
== Real-Time Clock
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,pm8058-rtc"
"qcom,pm8921-rtc"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: single entry specifying the base address of the RTC registers
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: single entry specifying the RTC's alarm interrupt
- allow-set-time:
Usage: optional
Value type: <empty>
Definition: indicates that the setting of RTC time is allowed by
the host CPU
= EXAMPLE
pmicintc: pmic@0 {
compatible = "qcom,pm8921";
interrupts = <104 8>;
#interrupt-cells = <2>;
interrupt-controller;
#address-cells = <1>;
#size-cells = <0>;
rtc@11d {
compatible = "qcom,pm8921-rtc";
reg = <0x11d>;
interrupts = <0x27 0>;
};
};
......@@ -16,20 +16,25 @@ Optional properties:
- interrupts: Interrupt specifiers for interrupt sources.
Optional nodes:
- clocks: s2mps11 provides three(AP/CP/BT) buffered 32.768 KHz outputs, so to
register these as clocks with common clock framework instantiate a sub-node
named "clocks". It uses the common clock binding documented in :
- clocks: s2mps11 and s5m8767 provide three(AP/CP/BT) buffered 32.768 KHz
outputs, so to register these as clocks with common clock framework
instantiate a sub-node named "clocks". It uses the common clock binding
documented in :
[Documentation/devicetree/bindings/clock/clock-bindings.txt]
The s2mps14 provides two (AP/BT) buffered 32.768 KHz outputs.
- #clock-cells: should be 1.
- The following is the list of clocks generated by the controller. Each clock
is assigned an identifier and client nodes use this identifier to specify
the clock which they consume.
Clock ID
----------------------
32KhzAP 0
32KhzCP 1
32KhzBT 2
Clock ID Devices
----------------------------------------------------------
32KhzAP 0 S2MPS11, S2MPS14, S5M8767
32KhzCP 1 S2MPS11, S5M8767
32KhzBT 2 S2MPS11, S2MPS14, S5M8767
- compatible: Should be one of: "samsung,s2mps11-clk", "samsung,s2mps14-clk",
"samsung,s5m8767-clk"
- regulators: The regulators of s2mps11 that have to be instantiated should be
included in a sub-node named 'regulators'. Regulator nodes included in this
......@@ -75,7 +80,8 @@ Example:
compatible = "samsung,s2mps11-pmic";
reg = <0x66>;
s2m_osc: clocks{
s2m_osc: clocks {
compatible = "samsung,s2mps11-clk";
#clock-cells = 1;
clock-output-names = "xx", "yy", "zz";
};
......
......@@ -733,6 +733,12 @@ usbhshost: usbhshost@4a064000 {
#address-cells = <1>;
#size-cells = <1>;
ranges;
clocks = <&init_60m_fclk>,
<&xclk60mhsp1_ck>,
<&xclk60mhsp2_ck>;
clock-names = "refclk_60m_int",
"refclk_60m_ext_p1",
"refclk_60m_ext_p2";
usbhsohci: ohci@4a064800 {
compatible = "ti,ohci-omap3";
......
......@@ -814,6 +814,12 @@ usbhshost: usbhshost@4a064000 {
#address-cells = <1>;
#size-cells = <1>;
ranges;
clocks = <&l3init_60m_fclk>,
<&xclk60mhsp1_ck>,
<&xclk60mhsp2_ck>;
clock-names = "refclk_60m_int",
"refclk_60m_ext_p1",
"refclk_60m_ext_p2";
usbhsohci: ohci@4a064800 {
compatible = "ti,ohci-omap3";
......
......@@ -3497,10 +3497,6 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "dss_tv_fck", &dss_tv_fck),
CLK(NULL, "dss_96m_fck", &dss_96m_fck),
CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck),
CLK(NULL, "utmi_p1_gfclk", &dummy_ck),
CLK(NULL, "utmi_p2_gfclk", &dummy_ck),
CLK(NULL, "xclk60mhsp1_ck", &dummy_ck),
CLK(NULL, "xclk60mhsp2_ck", &dummy_ck),
CLK(NULL, "init_60m_fclk", &dummy_ck),
CLK(NULL, "gpt1_fck", &gpt1_fck),
CLK(NULL, "aes2_ick", &aes2_ick),
......
......@@ -1955,10 +1955,6 @@ static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = {
.sysc = &omap3xxx_usb_host_hs_sysc,
};
static struct omap_hwmod_opt_clk omap3xxx_usb_host_hs_opt_clks[] = {
{ .role = "ehci_logic_fck", .clk = "usbhost_120m_fck", },
};
static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
{ .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, },
{ .name = "ehci-irq", .irq = 77 + OMAP_INTC_START, },
......@@ -1981,8 +1977,6 @@ static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
.idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT,
},
},
.opt_clks = omap3xxx_usb_host_hs_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(omap3xxx_usb_host_hs_opt_clks),
/*
* Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
......
......@@ -130,10 +130,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"),
DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"),
DT_CLK(NULL, "dss2_alwon_fck", "dss2_alwon_fck"),
DT_CLK(NULL, "utmi_p1_gfclk", "dummy_ck"),
DT_CLK(NULL, "utmi_p2_gfclk", "dummy_ck"),
DT_CLK(NULL, "xclk60mhsp1_ck", "dummy_ck"),
DT_CLK(NULL, "xclk60mhsp2_ck", "dummy_ck"),
DT_CLK(NULL, "init_60m_fclk", "dummy_ck"),
DT_CLK(NULL, "gpt1_fck", "gpt1_fck"),
DT_CLK(NULL, "aes2_ick", "aes2_ick"),
......
/*
* Intel ICH6-10, Series 5 and 6 GPIO driver
* Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver
*
* Copyright (C) 2010 Extreme Engineering Solutions.
*
......@@ -55,6 +55,16 @@ static const u8 ichx_reglen[3] = {
0x30, 0x10, 0x10,
};
static const u8 avoton_regs[4][3] = {
{0x00, 0x80, 0x00},
{0x04, 0x84, 0x00},
{0x08, 0x88, 0x00},
};
static const u8 avoton_reglen[3] = {
0x10, 0x10, 0x00,
};
#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start)
#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start)
......@@ -353,6 +363,17 @@ static struct ichx_desc intel5_desc = {
.reglen = ichx_reglen,
};
/* Avoton */
static struct ichx_desc avoton_desc = {
/* Avoton has only 59 GPIOs, but we assume the first set of register
* (Core) has 32 instead of 31 to keep gpio-ich compliance
*/
.ngpio = 60,
.regs = avoton_regs,
.reglen = avoton_reglen,
.use_outlvl_cache = true,
};
static int ichx_gpio_request_regions(struct resource *res_base,
const char *name, u8 use_gpio)
{
......@@ -427,6 +448,9 @@ static int ichx_gpio_probe(struct platform_device *pdev)
case ICH_V10CONS_GPIO:
ichx_priv.desc = &ich10_cons_desc;
break;
case AVOTON_GPIO:
ichx_priv.desc = &avoton_desc;
break;
default:
return -ENODEV;
}
......
......@@ -193,6 +193,16 @@ config TI_AM335X_ADC
Say yes here to build support for Texas Instruments ADC
driver which is also a MFD client.
config TWL4030_MADC
tristate "TWL4030 MADC (Monitoring A/D Converter)"
depends on TWL4030_CORE
help
This driver provides support for Triton TWL4030-MADC. The
driver supports both RT and SW conversion methods.
This driver can also be built as a module. If so, the module will be
called twl4030-madc.
config TWL6030_GPADC
tristate "TWL6030 GPADC (General Purpose A/D Converter) Support"
depends on TWL4030_CORE
......
......@@ -21,6 +21,7 @@ obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
obj-$(CONFIG_VF610_ADC) += vf610_adc.o
obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
......
......@@ -571,7 +571,7 @@ static int pm800_probe(struct i2c_client *client,
ret = pm800_pages_init(chip);
if (ret) {
dev_err(&client->dev, "pm800_pages_init failed!\n");
goto err_page_init;
goto err_device_init;
}
ret = device_800_init(chip, pdata);
......@@ -587,7 +587,6 @@ static int pm800_probe(struct i2c_client *client,
err_device_init:
pm800_pages_exit(chip);
err_page_init:
err_subchip_alloc:
pm80x_deinit();
out_init:
......
......@@ -1179,12 +1179,18 @@ static int pm860x_probe(struct i2c_client *client,
chip->companion_addr = pdata->companion_addr;
chip->companion = i2c_new_dummy(chip->client->adapter,
chip->companion_addr);
if (!chip->companion) {
dev_err(&client->dev,
"Failed to allocate I2C companion device\n");
return -ENODEV;
}
chip->regmap_companion = regmap_init_i2c(chip->companion,
&pm860x_regmap_config);
if (IS_ERR(chip->regmap_companion)) {
ret = PTR_ERR(chip->regmap_companion);
dev_err(&chip->companion->dev,
"Failed to allocate register map: %d\n", ret);
i2c_unregister_device(chip->companion);
return ret;
}
i2c_set_clientdata(chip->companion, chip);
......
......@@ -59,6 +59,14 @@ config MFD_AAT2870_CORE
additional drivers must be enabled in order to use the
functionality of the device.
config MFD_BCM590XX
tristate "Broadcom BCM590xx PMUs"
select MFD_CORE
select REGMAP_I2C
depends on I2C
help
Support for the BCM590xx PMUs from Broadcom
config MFD_CROS_EC
tristate "ChromeOS Embedded Controller"
select MFD_CORE
......@@ -100,7 +108,7 @@ config PMIC_DA903X
bool "Dialog Semiconductor DA9030/DA9034 PMIC Support"
depends on I2C=y
help
Say yes here to support for Dialog Semiconductor DA9030 (a.k.a
Say yes here to add support for Dialog Semiconductor DA9030 (a.k.a
ARAVA) and DA9034 (a.k.a MICCO), these are Power Management IC
usually found on PXA processors-based platforms. This includes
the I2C driver and the core APIs _only_, you have to select
......@@ -270,13 +278,18 @@ config MFD_KEMPLD
device may provide functions like watchdog, GPIO, UART and I2C bus.
The following modules are supported:
* COMe-bHL6
* COMe-bIP#
* COMe-bPC2 (ETXexpress-PC)
* COMe-bSC# (ETXexpress-SC T#)
* COMe-cBT6
* COMe-cCT6
* COMe-cDC2 (microETXexpress-DC)
* COMe-cHL6
* COMe-cPC2 (microETXexpress-PC)
* COMe-mBT10
* COMe-mCT10
* COMe-mTT10 (nanoETXexpress-TT)
* ETX-OH
This driver can also be built as a module. If so, the module
......@@ -322,9 +335,10 @@ config MFD_MAX14577
depends on I2C=y
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
select IRQ_DOMAIN
help
Say yes here to support for Maxim Semiconductor MAX14577.
Say yes here to add support for Maxim Semiconductor MAX14577.
This is a Micro-USB IC with Charger controls on chip.
This driver provides common support for accessing the device;
additional drivers must be enabled in order to use the functionality
......@@ -337,7 +351,7 @@ config MFD_MAX77686
select REGMAP_I2C
select IRQ_DOMAIN
help
Say yes here to support for Maxim Semiconductor MAX77686.
Say yes here to add support for Maxim Semiconductor MAX77686.
This is a Power Management IC with RTC on chip.
This driver provides common support for accessing the device;
additional drivers must be enabled in order to use the functionality
......@@ -349,7 +363,7 @@ config MFD_MAX77693
select MFD_CORE
select REGMAP_I2C
help
Say yes here to support for Maxim Semiconductor MAX77693.
Say yes here to add support for Maxim Semiconductor MAX77693.
This is a companion Power Management IC with Flash, Haptic, Charger,
and MUIC(Micro USB Interface Controller) controls on chip.
This driver provides common support for accessing the device;
......@@ -363,7 +377,7 @@ config MFD_MAX8907
select REGMAP_I2C
select REGMAP_IRQ
help
Say yes here to support for Maxim Semiconductor MAX8907. This is
Say yes here to add support for Maxim Semiconductor MAX8907. This is
a Power Management IC. This driver provides common support for
accessing the device; additional drivers must be enabled in order
to use the functionality of the device.
......@@ -373,7 +387,7 @@ config MFD_MAX8925
depends on I2C=y
select MFD_CORE
help
Say yes here to support for Maxim Semiconductor MAX8925. This is
Say yes here to add support for Maxim Semiconductor MAX8925. This is
a Power Management IC. This driver provides common support for
accessing the device, additional drivers must be enabled in order
to use the functionality of the device.
......@@ -384,7 +398,7 @@ config MFD_MAX8997
select MFD_CORE
select IRQ_DOMAIN
help
Say yes here to support for Maxim Semiconductor MAX8997/8966.
Say yes here to add support for Maxim Semiconductor MAX8997/8966.
This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
MUIC controls on chip.
This driver provides common support for accessing the device;
......@@ -397,7 +411,7 @@ config MFD_MAX8998
select MFD_CORE
select IRQ_DOMAIN
help
Say yes here to support for Maxim Semiconductor MAX8998 and
Say yes here to add support for Maxim Semiconductor MAX8998 and
National Semiconductor LP3974. This is a Power Management IC.
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the functionality
......@@ -473,10 +487,11 @@ config MFD_PM8XXX
config MFD_PM8921_CORE
tristate "Qualcomm PM8921 PMIC chip"
depends on (ARCH_MSM || HEXAGON)
depends on BROKEN
depends on (ARM || HEXAGON)
select IRQ_DOMAIN
select MFD_CORE
select MFD_PM8XXX
select REGMAP
help
If you say yes to this option, support will be included for the
built-in PM8921 PMIC chip.
......@@ -487,16 +502,6 @@ config MFD_PM8921_CORE
Say M here if you want to include support for PM8921 chip as a module.
This will build a module called "pm8921-core".
config MFD_PM8XXX_IRQ
bool "Qualcomm PM8xxx IRQ features"
depends on MFD_PM8XXX
default y if MFD_PM8XXX
help
This is the IRQ driver for Qualcomm PM 8xxx PMIC chips.
This is required to use certain other PM 8xxx features, such as GPIO
and MPP.
config MFD_RDC321X
tristate "RDC R-321x southbridge"
select MFD_CORE
......@@ -516,6 +521,16 @@ config MFD_RTSX_PCI
types of memory cards, such as Memory Stick, Memory Stick Pro,
Secure Digital and MultiMediaCard.
config MFD_RTSX_USB
tristate "Realtek USB card reader"
depends on USB
select MFD_CORE
help
Select this option to get support for Realtek USB 2.0 card readers
including RTS5129, RTS5139, RTS5179 and RTS5170.
Realtek card reader supports access to many types of memory cards,
such as Memory Stick Pro, Secure Digital and MultiMediaCard.
config MFD_RC5T583
bool "Ricoh RC5T583 Power Management system device"
depends on I2C=y
......@@ -774,17 +789,6 @@ config MFD_PALMAS
If you say yes here you get support for the Palmas
series of PMIC chips from Texas Instruments.
config MFD_TI_SSP
tristate "TI Sequencer Serial Port support"
depends on ARCH_DAVINCI_TNETV107X
select MFD_CORE
---help---
Say Y here if you want support for the Sequencer Serial Port
in a Texas Instruments TNETV107X SoC.
To compile this driver as a module, choose M here: the
module will be called ti-ssp.
config TPS6105X
tristate "TI TPS61050/61052 Boost Converters"
depends on I2C
......@@ -853,6 +857,22 @@ config MFD_TPS65217
This driver can also be built as a module. If so, the module
will be called tps65217.
config MFD_TPS65218
tristate "TI TPS65218 Power Management chips"
depends on I2C
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
help
If you say yes here you get support for the TPS65218 series of
Power Management chips.
These include voltage regulators, gpio and other features
that are often used in portable devices. Only regulator
component is currently supported.
This driver can also be built as a module. If so, the module
will be called tps65218.
config MFD_TPS6586X
bool "TI TPS6586x Power Management chips"
depends on I2C=y
......@@ -935,16 +955,6 @@ config TWL4030_CORE
high speed USB OTG transceiver, an audio codec (on most
versions) and many other features.
config TWL4030_MADC
tristate "TI TWL4030 MADC"
depends on TWL4030_CORE
help
This driver provides support for triton TWL4030-MADC. The
driver supports both RT and SW conversion methods.
This driver can be built as a module. If so it will be
named twl4030-madc
config TWL4030_POWER
bool "TI TWL4030 power resources"
depends on TWL4030_CORE && ARM
......@@ -1193,9 +1203,6 @@ config MFD_STW481X
in various ST Microelectronics and ST-Ericsson embedded
Nomadik series.
endmenu
endif
menu "Multimedia Capabilities Port drivers"
depends on ARCH_SA1100
......@@ -1226,3 +1233,6 @@ config VEXPRESS_CONFIG
help
Platform configuration infrastructure for the ARM Ltd.
Versatile Express.
endmenu
endif
......@@ -8,12 +8,14 @@ obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o
obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o
obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o
obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
......@@ -21,7 +23,6 @@ obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o
obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o
obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o
......@@ -62,6 +63,7 @@ obj-$(CONFIG_TPS6105X) += tps6105x.o
obj-$(CONFIG_TPS65010) += tps65010.o
obj-$(CONFIG_TPS6507X) += tps6507x.o
obj-$(CONFIG_MFD_TPS65217) += tps65217.o
obj-$(CONFIG_MFD_TPS65218) += tps65218.o
obj-$(CONFIG_MFD_TPS65910) += tps65910.o
tps65912-objs := tps65912-core.o tps65912-irq.o
obj-$(CONFIG_MFD_TPS65912) += tps65912.o
......@@ -71,7 +73,6 @@ obj-$(CONFIG_MFD_TPS80031) += tps80031.o
obj-$(CONFIG_MENELAUS) += menelaus.o
obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o
obj-$(CONFIG_TWL6040_CORE) += twl6040.o
......@@ -150,7 +151,6 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o
obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_TPS65090) += tps65090.o
obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
......
......@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
......
......@@ -277,6 +277,7 @@ static const struct regmap_range as3722_readable_ranges[] = {
regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG),
regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG),
regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
regmap_reg_range(AS3722_FUSE7_REG, AS3722_FUSE7_REG),
};
static const struct regmap_access_table as3722_readable_table = {
......
/*
* Broadcom BCM590xx PMU
*
* Copyright 2014 Linaro Limited
* Author: Matt Porter <mporter@linaro.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.
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/mfd/bcm590xx.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
static const struct mfd_cell bcm590xx_devs[] = {
{
.name = "bcm590xx-vregs",
},
};
static const struct regmap_config bcm590xx_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = BCM590XX_MAX_REGISTER,
.cache_type = REGCACHE_RBTREE,
};
static int bcm590xx_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct bcm590xx *bcm590xx;
int ret;
bcm590xx = devm_kzalloc(&i2c->dev, sizeof(*bcm590xx), GFP_KERNEL);
if (!bcm590xx)
return -ENOMEM;
i2c_set_clientdata(i2c, bcm590xx);
bcm590xx->dev = &i2c->dev;
bcm590xx->i2c_client = i2c;
bcm590xx->regmap = devm_regmap_init_i2c(i2c, &bcm590xx_regmap_config);
if (IS_ERR(bcm590xx->regmap)) {
ret = PTR_ERR(bcm590xx->regmap);
dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret);
return ret;
}
ret = mfd_add_devices(&i2c->dev, -1, bcm590xx_devs,
ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
if (ret < 0)
dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret);
return ret;
}
static const struct of_device_id bcm590xx_of_match[] = {
{ .compatible = "brcm,bcm59056" },
{ }
};
MODULE_DEVICE_TABLE(of, bcm590xx_of_match);
static const struct i2c_device_id bcm590xx_i2c_id[] = {
{ "bcm59056" },
{ }
};
MODULE_DEVICE_TABLE(i2c, bcm590xx_i2c_id);
static struct i2c_driver bcm590xx_i2c_driver = {
.driver = {
.name = "bcm590xx",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(bcm590xx_of_match),
},
.probe = bcm590xx_i2c_probe,
.id_table = bcm590xx_i2c_id,
};
module_i2c_driver(bcm590xx_i2c_driver);
MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
MODULE_DESCRIPTION("BCM590xx multi-function driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:bcm590xx");
......@@ -23,7 +23,6 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/pci.h>
......
......@@ -279,6 +279,9 @@ static bool da9052_reg_volatile(struct device *dev, unsigned int reg)
case DA9052_EVENT_B_REG:
case DA9052_EVENT_C_REG:
case DA9052_EVENT_D_REG:
case DA9052_CONTROL_B_REG:
case DA9052_CONTROL_D_REG:
case DA9052_SUPPLY_REG:
case DA9052_FAULTLOG_REG:
case DA9052_CHG_TIME_REG:
case DA9052_ADC_RES_L_REG:
......
......@@ -75,6 +75,7 @@ static int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
DA9052_PARK_REGISTER,
&val);
break;
case DA9053_BC:
default:
/*
* For other chips parking of I2C register
......@@ -114,6 +115,7 @@ static const struct i2c_device_id da9052_i2c_id[] = {
{"da9053-aa", DA9053_AA},
{"da9053-ba", DA9053_BA},
{"da9053-bb", DA9053_BB},
{"da9053-bc", DA9053_BC},
{}
};
......@@ -121,8 +123,9 @@ static const struct i2c_device_id da9052_i2c_id[] = {
static const struct of_device_id dialog_dt_ids[] = {
{ .compatible = "dlg,da9052", .data = &da9052_i2c_id[0] },
{ .compatible = "dlg,da9053-aa", .data = &da9052_i2c_id[1] },
{ .compatible = "dlg,da9053-ab", .data = &da9052_i2c_id[2] },
{ .compatible = "dlg,da9053-ba", .data = &da9052_i2c_id[2] },
{ .compatible = "dlg,da9053-bb", .data = &da9052_i2c_id[3] },
{ .compatible = "dlg,da9053-bc", .data = &da9052_i2c_id[4] },
{ /* sentinel */ }
};
#endif
......
......@@ -71,6 +71,7 @@ static struct spi_device_id da9052_spi_id[] = {
{"da9053-aa", DA9053_AA},
{"da9053-ba", DA9053_BA},
{"da9053-bb", DA9053_BB},
{"da9053-bc", DA9053_BC},
{}
};
......
......@@ -15,6 +15,8 @@
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/mfd/da9055/core.h>
......@@ -66,6 +68,11 @@ static struct i2c_device_id da9055_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
static const struct of_device_id da9055_of_match[] = {
{ .compatible = "dlg,da9055-pmic", },
{ }
};
static struct i2c_driver da9055_i2c_driver = {
.probe = da9055_i2c_probe,
.remove = da9055_i2c_remove,
......@@ -73,6 +80,7 @@ static struct i2c_driver da9055_i2c_driver = {
.driver = {
.name = "da9055-pmic",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(da9055_of_match),
},
};
......
......@@ -110,7 +110,7 @@ static const struct mfd_cell da9063_devs[] = {
int da9063_device_init(struct da9063 *da9063, unsigned int irq)
{
struct da9063_pdata *pdata = da9063->dev->platform_data;
int model, revision;
int model, variant_id, variant_code;
int ret;
if (pdata) {
......@@ -141,23 +141,26 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
return -ENODEV;
}
ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &revision);
ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &variant_id);
if (ret < 0) {
dev_err(da9063->dev, "Cannot read chip revision id.\n");
dev_err(da9063->dev, "Cannot read chip variant id.\n");
return -EIO;
}
revision >>= DA9063_CHIP_VARIANT_SHIFT;
if (revision != 3) {
dev_err(da9063->dev, "Unknown chip revision: %d\n", revision);
variant_code = variant_id >> DA9063_CHIP_VARIANT_SHIFT;
dev_info(da9063->dev,
"Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n",
model, variant_id);
if (variant_code != PMIC_DA9063_BB) {
dev_err(da9063->dev, "Unknown chip variant code: 0x%02X\n",
variant_code);
return -ENODEV;
}
da9063->model = model;
da9063->revision = revision;
dev_info(da9063->dev,
"Device detected (model-ID: 0x%02X rev-ID: 0x%02X)\n",
model, revision);
da9063->variant_code = variant_code;
ret = da9063_irq_init(da9063);
if (ret) {
......
......@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
......
......@@ -322,9 +322,12 @@ static int kempld_detect_device(struct kempld_device_data *pld)
return -ENODEV;
}
/* Release hardware mutex if aquired */
if (!(index_reg & KEMPLD_MUTEX_KEY))
/* Release hardware mutex if acquired */
if (!(index_reg & KEMPLD_MUTEX_KEY)) {
iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
/* PXT and COMe-cPC2 boards may require a second release */
iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
}
mutex_unlock(&pld->lock);
......@@ -437,6 +440,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, {
.ident = "CHL6",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
DMI_MATCH(DMI_BOARD_NAME, "COMe-cHL6"),
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, {
.ident = "CHR2",
.matches = {
......@@ -509,6 +520,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, {
.ident = "CVV6",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
DMI_MATCH(DMI_BOARD_NAME, "COMe-cBT"),
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, {
.ident = "FRI2",
.matches = {
......@@ -532,6 +551,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, {
.ident = "MVV1",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
DMI_MATCH(DMI_BOARD_NAME, "COMe-mBT"),
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, {
.ident = "NTC1",
.matches = {
......
......@@ -58,7 +58,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
......@@ -72,9 +71,11 @@
#define ACPIBASE_GPE_END 0x2f
#define ACPIBASE_SMI_OFF 0x30
#define ACPIBASE_SMI_END 0x33
#define ACPIBASE_PMC_OFF 0x08
#define ACPIBASE_PMC_END 0x0c
#define ACPIBASE_TCO_OFF 0x60
#define ACPIBASE_TCO_END 0x7f
#define ACPICTRL 0x44
#define ACPICTRL_PMCBASE 0x44
#define ACPIBASE_GCS_OFF 0x3410
#define ACPIBASE_GCS_END 0x3414
......@@ -90,16 +91,17 @@
#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i)
#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)])
struct lpc_ich_cfg {
int base;
int ctrl;
int save;
};
struct lpc_ich_priv {
int chipset;
struct lpc_ich_cfg acpi;
struct lpc_ich_cfg gpio;
int abase; /* ACPI base */
int actrl_pbase; /* ACPI control or PMC base */
int gbase; /* GPIO base */
int gctrl; /* GPIO control */
int abase_save; /* Cached ACPI base value */
int actrl_pbase_save; /* Cached ACPI control or PMC base value */
int gctrl_save; /* Cached GPIO control value */
};
static struct resource wdt_ich_res[] = {
......@@ -111,7 +113,7 @@ static struct resource wdt_ich_res[] = {
{
.flags = IORESOURCE_IO,
},
/* GCS */
/* GCS or PMC */
{
.flags = IORESOURCE_MEM,
},
......@@ -211,6 +213,7 @@ enum lpc_chipsets {
LPC_LPT_LP, /* Lynx Point-LP */
LPC_WBG, /* Wellsburg */
LPC_AVN, /* Avoton SoC */
LPC_BAYTRAIL, /* Bay Trail SoC */
LPC_COLETO, /* Coleto Creek */
LPC_WPT_LP, /* Wildcat Point-LP */
};
......@@ -303,6 +306,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
[LPC_NM10] = {
.name = "NM10",
.iTCO_version = 2,
.gpio_version = ICH_V7_GPIO,
},
[LPC_ICH8] = {
.name = "ICH8 or ICH8R",
......@@ -499,7 +503,12 @@ static struct lpc_ich_info lpc_chipset_info[] = {
},
[LPC_AVN] = {
.name = "Avoton SoC",
.iTCO_version = 1,
.iTCO_version = 3,
.gpio_version = AVOTON_GPIO,
},
[LPC_BAYTRAIL] = {
.name = "Bay Trail SoC",
.iTCO_version = 3,
},
[LPC_COLETO] = {
.name = "Coleto Creek",
......@@ -726,6 +735,7 @@ static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL},
{ PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO},
{ PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP},
{ PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP},
......@@ -742,14 +752,20 @@ static void lpc_ich_restore_config_space(struct pci_dev *dev)
{
struct lpc_ich_priv *priv = pci_get_drvdata(dev);
if (priv->acpi.save >= 0) {
pci_write_config_byte(dev, priv->acpi.ctrl, priv->acpi.save);
priv->acpi.save = -1;
if (priv->abase_save >= 0) {
pci_write_config_byte(dev, priv->abase, priv->abase_save);
priv->abase_save = -1;
}
if (priv->actrl_pbase_save >= 0) {
pci_write_config_byte(dev, priv->actrl_pbase,
priv->actrl_pbase_save);
priv->actrl_pbase_save = -1;
}
if (priv->gpio.save >= 0) {
pci_write_config_byte(dev, priv->gpio.ctrl, priv->gpio.save);
priv->gpio.save = -1;
if (priv->gctrl_save >= 0) {
pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save);
priv->gctrl_save = -1;
}
}
......@@ -758,9 +774,26 @@ static void lpc_ich_enable_acpi_space(struct pci_dev *dev)
struct lpc_ich_priv *priv = pci_get_drvdata(dev);
u8 reg_save;
pci_read_config_byte(dev, priv->acpi.ctrl, &reg_save);
pci_write_config_byte(dev, priv->acpi.ctrl, reg_save | 0x10);
priv->acpi.save = reg_save;
switch (lpc_chipset_info[priv->chipset].iTCO_version) {
case 3:
/*
* Some chipsets (eg Avoton) enable the ACPI space in the
* ACPI BASE register.
*/
pci_read_config_byte(dev, priv->abase, &reg_save);
pci_write_config_byte(dev, priv->abase, reg_save | 0x2);
priv->abase_save = reg_save;
break;
default:
/*
* Most chipsets enable the ACPI space in the ACPI control
* register.
*/
pci_read_config_byte(dev, priv->actrl_pbase, &reg_save);
pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80);
priv->actrl_pbase_save = reg_save;
break;
}
}
static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
......@@ -768,9 +801,20 @@ static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
struct lpc_ich_priv *priv = pci_get_drvdata(dev);
u8 reg_save;
pci_read_config_byte(dev, priv->gpio.ctrl, &reg_save);
pci_write_config_byte(dev, priv->gpio.ctrl, reg_save | 0x10);
priv->gpio.save = reg_save;
pci_read_config_byte(dev, priv->gctrl, &reg_save);
pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10);
priv->gctrl_save = reg_save;
}
static void lpc_ich_enable_pmc_space(struct pci_dev *dev)
{
struct lpc_ich_priv *priv = pci_get_drvdata(dev);
u8 reg_save;
pci_read_config_byte(dev, priv->actrl_pbase, &reg_save);
pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2);
priv->actrl_pbase_save = reg_save;
}
static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell)
......@@ -815,7 +859,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev)
struct resource *res;
/* Setup power management base register */
pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg);
pci_read_config_dword(dev, priv->abase, &base_addr_cfg);
base_addr = base_addr_cfg & 0x0000ff80;
if (!base_addr) {
dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
......@@ -841,7 +885,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev)
gpe0_done:
/* Setup GPIO base register */
pci_read_config_dword(dev, priv->gpio.base, &base_addr_cfg);
pci_read_config_dword(dev, priv->gbase, &base_addr_cfg);
base_addr = base_addr_cfg & 0x0000ff80;
if (!base_addr) {
dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n");
......@@ -891,7 +935,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
struct resource *res;
/* Setup power management base register */
pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg);
pci_read_config_dword(dev, priv->abase, &base_addr_cfg);
base_addr = base_addr_cfg & 0x0000ff80;
if (!base_addr) {
dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
......@@ -910,14 +954,20 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
lpc_ich_enable_acpi_space(dev);
/*
* iTCO v2:
* Get the Memory-Mapped GCS register. To get access to it
* we have to read RCBA from PCI Config space 0xf0 and use
* it as base. GCS = RCBA + ICH6_GCS(0x3410).
*
* iTCO v3:
* Get the Power Management Configuration register. To get access
* to it we have to read the PMC BASE from config space and address
* the register at offset 0x8.
*/
if (lpc_chipset_info[priv->chipset].iTCO_version == 1) {
/* Don't register iomem for TCO ver 1 */
lpc_ich_cells[LPC_WDT].num_resources--;
} else {
} else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) {
pci_read_config_dword(dev, RCBABASE, &base_addr_cfg);
base_addr = base_addr_cfg & 0xffffc000;
if (!(base_addr_cfg & 1)) {
......@@ -926,9 +976,17 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
ret = -ENODEV;
goto wdt_done;
}
res = wdt_mem_res(ICH_RES_MEM_GCS);
res = wdt_mem_res(ICH_RES_MEM_GCS_PMC);
res->start = base_addr + ACPIBASE_GCS_OFF;
res->end = base_addr + ACPIBASE_GCS_END;
} else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) {
lpc_ich_enable_pmc_space(dev);
pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg);
base_addr = base_addr_cfg & 0xfffffe00;
res = wdt_mem_res(ICH_RES_MEM_GCS_PMC);
res->start = base_addr + ACPIBASE_PMC_OFF;
res->end = base_addr + ACPIBASE_PMC_END;
}
lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]);
......@@ -952,28 +1010,35 @@ static int lpc_ich_probe(struct pci_dev *dev,
return -ENOMEM;
priv->chipset = id->driver_data;
priv->acpi.save = -1;
priv->acpi.base = ACPIBASE;
priv->acpi.ctrl = ACPICTRL;
priv->gpio.save = -1;
priv->actrl_pbase_save = -1;
priv->abase_save = -1;
priv->abase = ACPIBASE;
priv->actrl_pbase = ACPICTRL_PMCBASE;
priv->gctrl_save = -1;
if (priv->chipset <= LPC_ICH5) {
priv->gpio.base = GPIOBASE_ICH0;
priv->gpio.ctrl = GPIOCTRL_ICH0;
priv->gbase = GPIOBASE_ICH0;
priv->gctrl = GPIOCTRL_ICH0;
} else {
priv->gpio.base = GPIOBASE_ICH6;
priv->gpio.ctrl = GPIOCTRL_ICH6;
priv->gbase = GPIOBASE_ICH6;
priv->gctrl = GPIOCTRL_ICH6;
}
pci_set_drvdata(dev, priv);
ret = lpc_ich_init_wdt(dev);
if (!ret)
cell_added = true;
if (lpc_chipset_info[priv->chipset].iTCO_version) {
ret = lpc_ich_init_wdt(dev);
if (!ret)
cell_added = true;
}
ret = lpc_ich_init_gpio(dev);
if (!ret)
cell_added = true;
if (lpc_chipset_info[priv->chipset].gpio_version) {
ret = lpc_ich_init_gpio(dev);
if (!ret)
cell_added = true;
}
/*
* We only care if at least one or none of the cells registered
......
......@@ -23,7 +23,6 @@
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
......
......@@ -18,6 +18,7 @@
* This driver is based on max8997.c
*/
#include <linux/err.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
......@@ -25,7 +26,10 @@
#include <linux/mfd/max14577-private.h>
static struct mfd_cell max14577_devs[] = {
{ .name = "max14577-muic", },
{
.name = "max14577-muic",
.of_compatible = "maxim,max14577-muic",
},
{
.name = "max14577-regulator",
.of_compatible = "maxim,max14577-regulator",
......
......@@ -121,6 +121,10 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
dev_info(max77686->dev, "device found\n");
max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
if (!max77686->rtc) {
dev_err(max77686->dev, "Failed to allocate I2C device for RTC\n");
return -ENODEV;
}
i2c_set_clientdata(max77686->rtc, max77686);
max77686_irq_init(max77686);
......
......@@ -148,9 +148,18 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
if (!max77693->muic) {
dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n");
return -ENODEV;
}
i2c_set_clientdata(max77693->muic, max77693);
max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
if (!max77693->haptic) {
dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n");
ret = -ENODEV;
goto err_i2c_haptic;
}
i2c_set_clientdata(max77693->haptic, max77693);
/*
......@@ -184,8 +193,9 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
max77693_irq_exit(max77693);
err_irq:
err_regmap_muic:
i2c_unregister_device(max77693->muic);
i2c_unregister_device(max77693->haptic);
err_i2c_haptic:
i2c_unregister_device(max77693->muic);
return ret;
}
......
......@@ -181,9 +181,18 @@ static int max8925_probe(struct i2c_client *client,
mutex_init(&chip->io_lock);
chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
if (!chip->rtc) {
dev_err(chip->dev, "Failed to allocate I2C device for RTC\n");
return -ENODEV;
}
i2c_set_clientdata(chip->rtc, chip);
chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
if (!chip->adc) {
dev_err(chip->dev, "Failed to allocate I2C device for ADC\n");
i2c_unregister_device(chip->rtc);
return -ENODEV;
}
i2c_set_clientdata(chip->adc, chip);
device_init_wakeup(&client->dev, 1);
......
......@@ -208,10 +208,26 @@ 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) {
dev_err(max8997->dev, "Failed to allocate I2C device for RTC\n");
return -ENODEV;
}
i2c_set_clientdata(max8997->rtc, max8997);
max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
if (!max8997->haptic) {
dev_err(max8997->dev, "Failed to allocate I2C device for Haptic\n");
ret = -ENODEV;
goto err_i2c_haptic;
}
i2c_set_clientdata(max8997->haptic, max8997);
max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
if (!max8997->muic) {
dev_err(max8997->dev, "Failed to allocate I2C device for MUIC\n");
ret = -ENODEV;
goto err_i2c_muic;
}
i2c_set_clientdata(max8997->muic, max8997);
pm_runtime_set_active(max8997->dev);
......@@ -239,7 +255,9 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
err_mfd:
mfd_remove_devices(max8997->dev);
i2c_unregister_device(max8997->muic);
err_i2c_muic:
i2c_unregister_device(max8997->haptic);
err_i2c_haptic:
i2c_unregister_device(max8997->rtc);
return ret;
}
......
......@@ -215,6 +215,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) {
dev_err(&i2c->dev, "Failed to allocate I2C device for RTC\n");
return -ENODEV;
}
i2c_set_clientdata(max8998->rtc, max8998);
max8998_irq_init(max8998);
......
......@@ -140,6 +140,11 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
mc13xxx->irq = spi->irq;
spi->max_speed_hz = spi->max_speed_hz ? : 26000000;
ret = spi_setup(spi);
if (ret)
return ret;
mc13xxx->regmap = devm_regmap_init(&spi->dev, &regmap_mc13xxx_bus,
&spi->dev,
&mc13xxx_regmap_spi_config);
......
......@@ -12,7 +12,6 @@
* MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/kernel.h>
......
......@@ -665,55 +665,78 @@ static int usbhs_omap_probe(struct platform_device *pdev)
goto err_mem;
}
need_logic_fck = false;
/* Set all clocks as invalid to begin with */
omap->ehci_logic_fck = ERR_PTR(-ENODEV);
omap->init_60m_fclk = ERR_PTR(-ENODEV);
omap->utmi_p1_gfclk = ERR_PTR(-ENODEV);
omap->utmi_p2_gfclk = ERR_PTR(-ENODEV);
omap->xclk60mhsp1_ck = ERR_PTR(-ENODEV);
omap->xclk60mhsp2_ck = ERR_PTR(-ENODEV);
for (i = 0; i < omap->nports; i++) {
if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
is_ehci_hsic_mode(i))
need_logic_fck |= true;
omap->utmi_clk[i] = ERR_PTR(-ENODEV);
omap->hsic480m_clk[i] = ERR_PTR(-ENODEV);
omap->hsic60m_clk[i] = ERR_PTR(-ENODEV);
}
omap->ehci_logic_fck = ERR_PTR(-EINVAL);
if (need_logic_fck) {
omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
if (IS_ERR(omap->ehci_logic_fck)) {
ret = PTR_ERR(omap->ehci_logic_fck);
dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
/* for OMAP3 i.e. USBHS REV1 */
if (omap->usbhs_rev == OMAP_USBHS_REV1) {
need_logic_fck = false;
for (i = 0; i < omap->nports; i++) {
if (is_ehci_phy_mode(pdata->port_mode[i]) ||
is_ehci_tll_mode(pdata->port_mode[i]) ||
is_ehci_hsic_mode(pdata->port_mode[i]))
need_logic_fck |= true;
}
if (need_logic_fck) {
omap->ehci_logic_fck = devm_clk_get(dev,
"usbhost_120m_fck");
if (IS_ERR(omap->ehci_logic_fck)) {
ret = PTR_ERR(omap->ehci_logic_fck);
dev_err(dev, "usbhost_120m_fck failed:%d\n",
ret);
goto err_mem;
}
}
goto initialize;
}
omap->utmi_p1_gfclk = clk_get(dev, "utmi_p1_gfclk");
/* for OMAP4+ i.e. USBHS REV2+ */
omap->utmi_p1_gfclk = devm_clk_get(dev, "utmi_p1_gfclk");
if (IS_ERR(omap->utmi_p1_gfclk)) {
ret = PTR_ERR(omap->utmi_p1_gfclk);
dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
goto err_p1_gfclk;
goto err_mem;
}
omap->utmi_p2_gfclk = clk_get(dev, "utmi_p2_gfclk");
omap->utmi_p2_gfclk = devm_clk_get(dev, "utmi_p2_gfclk");
if (IS_ERR(omap->utmi_p2_gfclk)) {
ret = PTR_ERR(omap->utmi_p2_gfclk);
dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
goto err_p2_gfclk;
goto err_mem;
}
omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1");
if (IS_ERR(omap->xclk60mhsp1_ck)) {
ret = PTR_ERR(omap->xclk60mhsp1_ck);
dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
goto err_xclk60mhsp1;
dev_err(dev, "refclk_60m_ext_p1 failed error:%d\n", ret);
goto err_mem;
}
omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2");
if (IS_ERR(omap->xclk60mhsp2_ck)) {
ret = PTR_ERR(omap->xclk60mhsp2_ck);
dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
goto err_xclk60mhsp2;
dev_err(dev, "refclk_60m_ext_p2 failed error:%d\n", ret);
goto err_mem;
}
omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int");
if (IS_ERR(omap->init_60m_fclk)) {
ret = PTR_ERR(omap->init_60m_fclk);
dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
goto err_init60m;
dev_err(dev, "refclk_60m_int failed error:%d\n", ret);
goto err_mem;
}
for (i = 0; i < omap->nports; i++) {
......@@ -727,55 +750,72 @@ static int usbhs_omap_probe(struct platform_device *pdev)
* platforms have all clocks and we can function without
* them
*/
omap->utmi_clk[i] = clk_get(dev, clkname);
if (IS_ERR(omap->utmi_clk[i]))
dev_dbg(dev, "Failed to get clock : %s : %ld\n",
clkname, PTR_ERR(omap->utmi_clk[i]));
omap->utmi_clk[i] = devm_clk_get(dev, clkname);
if (IS_ERR(omap->utmi_clk[i])) {
ret = PTR_ERR(omap->utmi_clk[i]);
dev_err(dev, "Failed to get clock : %s : %d\n",
clkname, ret);
goto err_mem;
}
snprintf(clkname, sizeof(clkname),
"usb_host_hs_hsic480m_p%d_clk", i + 1);
omap->hsic480m_clk[i] = clk_get(dev, clkname);
if (IS_ERR(omap->hsic480m_clk[i]))
dev_dbg(dev, "Failed to get clock : %s : %ld\n",
clkname, PTR_ERR(omap->hsic480m_clk[i]));
omap->hsic480m_clk[i] = devm_clk_get(dev, clkname);
if (IS_ERR(omap->hsic480m_clk[i])) {
ret = PTR_ERR(omap->hsic480m_clk[i]);
dev_err(dev, "Failed to get clock : %s : %d\n",
clkname, ret);
goto err_mem;
}
snprintf(clkname, sizeof(clkname),
"usb_host_hs_hsic60m_p%d_clk", i + 1);
omap->hsic60m_clk[i] = clk_get(dev, clkname);
if (IS_ERR(omap->hsic60m_clk[i]))
dev_dbg(dev, "Failed to get clock : %s : %ld\n",
clkname, PTR_ERR(omap->hsic60m_clk[i]));
omap->hsic60m_clk[i] = devm_clk_get(dev, clkname);
if (IS_ERR(omap->hsic60m_clk[i])) {
ret = PTR_ERR(omap->hsic60m_clk[i]);
dev_err(dev, "Failed to get clock : %s : %d\n",
clkname, ret);
goto err_mem;
}
}
if (is_ehci_phy_mode(pdata->port_mode[0])) {
/* for OMAP3, clk_set_parent fails */
ret = clk_set_parent(omap->utmi_p1_gfclk,
omap->xclk60mhsp1_ck);
if (ret != 0)
dev_dbg(dev, "xclk60mhsp1_ck set parent failed: %d\n",
ret);
if (ret != 0) {
dev_err(dev, "xclk60mhsp1_ck set parent failed: %d\n",
ret);
goto err_mem;
}
} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
ret = clk_set_parent(omap->utmi_p1_gfclk,
omap->init_60m_fclk);
if (ret != 0)
dev_dbg(dev, "P0 init_60m_fclk set parent failed: %d\n",
ret);
if (ret != 0) {
dev_err(dev, "P0 init_60m_fclk set parent failed: %d\n",
ret);
goto err_mem;
}
}
if (is_ehci_phy_mode(pdata->port_mode[1])) {
ret = clk_set_parent(omap->utmi_p2_gfclk,
omap->xclk60mhsp2_ck);
if (ret != 0)
dev_dbg(dev, "xclk60mhsp2_ck set parent failed: %d\n",
ret);
if (ret != 0) {
dev_err(dev, "xclk60mhsp2_ck set parent failed: %d\n",
ret);
goto err_mem;
}
} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
ret = clk_set_parent(omap->utmi_p2_gfclk,
omap->init_60m_fclk);
if (ret != 0)
dev_dbg(dev, "P1 init_60m_fclk set parent failed: %d\n",
ret);
if (ret != 0) {
dev_err(dev, "P1 init_60m_fclk set parent failed: %d\n",
ret);
goto err_mem;
}
}
initialize:
omap_usbhs_init(dev);
if (dev->of_node) {
......@@ -784,7 +824,7 @@ static int usbhs_omap_probe(struct platform_device *pdev)
if (ret) {
dev_err(dev, "Failed to create DT children: %d\n", ret);
goto err_alloc;
goto err_mem;
}
} else {
......@@ -792,40 +832,12 @@ static int usbhs_omap_probe(struct platform_device *pdev)
if (ret) {
dev_err(dev, "omap_usbhs_alloc_children failed: %d\n",
ret);
goto err_alloc;
goto err_mem;
}
}
return 0;
err_alloc:
for (i = 0; i < omap->nports; i++) {
if (!IS_ERR(omap->utmi_clk[i]))
clk_put(omap->utmi_clk[i]);
if (!IS_ERR(omap->hsic60m_clk[i]))
clk_put(omap->hsic60m_clk[i]);
if (!IS_ERR(omap->hsic480m_clk[i]))
clk_put(omap->hsic480m_clk[i]);
}
clk_put(omap->init_60m_fclk);
err_init60m:
clk_put(omap->xclk60mhsp2_ck);
err_xclk60mhsp2:
clk_put(omap->xclk60mhsp1_ck);
err_xclk60mhsp1:
clk_put(omap->utmi_p2_gfclk);
err_p2_gfclk:
clk_put(omap->utmi_p1_gfclk);
err_p1_gfclk:
if (!IS_ERR(omap->ehci_logic_fck))
clk_put(omap->ehci_logic_fck);
err_mem:
pm_runtime_disable(dev);
......@@ -847,27 +859,6 @@ static int usbhs_omap_remove_child(struct device *dev, void *data)
*/
static int usbhs_omap_remove(struct platform_device *pdev)
{
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
int i;
for (i = 0; i < omap->nports; i++) {
if (!IS_ERR(omap->utmi_clk[i]))
clk_put(omap->utmi_clk[i]);
if (!IS_ERR(omap->hsic60m_clk[i]))
clk_put(omap->hsic60m_clk[i]);
if (!IS_ERR(omap->hsic480m_clk[i]))
clk_put(omap->hsic480m_clk[i]);
}
clk_put(omap->init_60m_fclk);
clk_put(omap->utmi_p1_gfclk);
clk_put(omap->utmi_p2_gfclk);
clk_put(omap->xclk60mhsp2_ck);
clk_put(omap->xclk60mhsp1_ck);
if (!IS_ERR(omap->ehci_logic_fck))
clk_put(omap->ehci_logic_fck);
pm_runtime_disable(&pdev->dev);
/* remove children */
......
......@@ -252,7 +252,7 @@ static int usbtll_omap_probe(struct platform_device *pdev)
break;
}
tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]),
tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk *) * tll->nch,
GFP_KERNEL);
if (!tll->ch_clk) {
ret = -ENOMEM;
......
......@@ -19,7 +19,6 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/completion.h>
......
This diff is collapsed.
/*
* Copyright (c) 2011, Code Aurora Forum. 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 and
* only 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.
*/
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/mfd/pm8xxx/core.h>
#include <linux/mfd/pm8xxx/irq.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
/* PMIC8xxx IRQ */
#define SSBI_REG_ADDR_IRQ_BASE 0x1BB
#define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0)
#define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1)
#define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2)
#define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3)
#define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4)
#define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5)
#define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6)
#define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7)
#define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8)
#define PM_IRQF_LVL_SEL 0x01 /* level select */
#define PM_IRQF_MASK_FE 0x02 /* mask falling edge */
#define PM_IRQF_MASK_RE 0x04 /* mask rising edge */
#define PM_IRQF_CLR 0x08 /* clear interrupt */
#define PM_IRQF_BITS_MASK 0x70
#define PM_IRQF_BITS_SHIFT 4
#define PM_IRQF_WRITE 0x80
#define PM_IRQF_MASK_ALL (PM_IRQF_MASK_FE | \
PM_IRQF_MASK_RE)
struct pm_irq_chip {
struct device *dev;
spinlock_t pm_irq_lock;
unsigned int devirq;
unsigned int irq_base;
unsigned int num_irqs;
unsigned int num_blocks;
unsigned int num_masters;
u8 config[0];
};
static int pm8xxx_read_root_irq(const struct pm_irq_chip *chip, u8 *rp)
{
return pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp);
}
static int pm8xxx_read_master_irq(const struct pm_irq_chip *chip, u8 m, u8 *bp)
{
return pm8xxx_readb(chip->dev,
SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp);
}
static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip)
{
int rc;
spin_lock(&chip->pm_irq_lock);
rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
if (rc) {
pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
goto bail;
}
rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
if (rc)
pr_err("Failed Reading Status rc=%d\n", rc);
bail:
spin_unlock(&chip->pm_irq_lock);
return rc;
}
static int pm8xxx_config_irq(struct pm_irq_chip *chip, u8 bp, u8 cp)
{
int rc;
spin_lock(&chip->pm_irq_lock);
rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
if (rc) {
pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
goto bail;
}
cp |= PM_IRQF_WRITE;
rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp);
if (rc)
pr_err("Failed Configuring IRQ rc=%d\n", rc);
bail:
spin_unlock(&chip->pm_irq_lock);
return rc;
}
static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
{
int pmirq, irq, i, ret = 0;
u8 bits;
ret = pm8xxx_read_block_irq(chip, block, &bits);
if (ret) {
pr_err("Failed reading %d block ret=%d", block, ret);
return ret;
}
if (!bits) {
pr_err("block bit set in master but no irqs: %d", block);
return 0;
}
/* Check IRQ bits */
for (i = 0; i < 8; i++) {
if (bits & (1 << i)) {
pmirq = block * 8 + i;
irq = pmirq + chip->irq_base;
generic_handle_irq(irq);
}
}
return 0;
}
static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)
{
u8 blockbits;
int block_number, i, ret = 0;
ret = pm8xxx_read_master_irq(chip, master, &blockbits);
if (ret) {
pr_err("Failed to read master %d ret=%d\n", master, ret);
return ret;
}
if (!blockbits) {
pr_err("master bit set in root but no blocks: %d", master);
return 0;
}
for (i = 0; i < 8; i++)
if (blockbits & (1 << i)) {
block_number = master * 8 + i; /* block # */
ret |= pm8xxx_irq_block_handler(chip, block_number);
}
return ret;
}
static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc)
{
struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
struct irq_chip *irq_chip = irq_desc_get_chip(desc);
u8 root;
int i, ret, masters = 0;
ret = pm8xxx_read_root_irq(chip, &root);
if (ret) {
pr_err("Can't read root status ret=%d\n", ret);
return;
}
/* on pm8xxx series masters start from bit 1 of the root */
masters = root >> 1;
/* Read allowed masters for blocks. */
for (i = 0; i < chip->num_masters; i++)
if (masters & (1 << i))
pm8xxx_irq_master_handler(chip, i);
irq_chip->irq_ack(&desc->irq_data);
}
static void pm8xxx_irq_mask_ack(struct irq_data *d)
{
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
unsigned int pmirq = d->irq - chip->irq_base;
int master, irq_bit;
u8 block, config;
block = pmirq / 8;
master = block / 8;
irq_bit = pmirq % 8;
config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
pm8xxx_config_irq(chip, block, config);
}
static void pm8xxx_irq_unmask(struct irq_data *d)
{
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
unsigned int pmirq = d->irq - chip->irq_base;
int master, irq_bit;
u8 block, config;
block = pmirq / 8;
master = block / 8;
irq_bit = pmirq % 8;
config = chip->config[pmirq];
pm8xxx_config_irq(chip, block, config);
}
static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
unsigned int pmirq = d->irq - chip->irq_base;
int master, irq_bit;
u8 block, config;
block = pmirq / 8;
master = block / 8;
irq_bit = pmirq % 8;
chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT)
| PM_IRQF_MASK_ALL;
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
if (flow_type & IRQF_TRIGGER_RISING)
chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
if (flow_type & IRQF_TRIGGER_FALLING)
chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
} else {
chip->config[pmirq] |= PM_IRQF_LVL_SEL;
if (flow_type & IRQF_TRIGGER_HIGH)
chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
else
chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
}
config = chip->config[pmirq] | PM_IRQF_CLR;
return pm8xxx_config_irq(chip, block, config);
}
static int pm8xxx_irq_set_wake(struct irq_data *d, unsigned int on)
{
return 0;
}
static struct irq_chip pm8xxx_irq_chip = {
.name = "pm8xxx",
.irq_mask_ack = pm8xxx_irq_mask_ack,
.irq_unmask = pm8xxx_irq_unmask,
.irq_set_type = pm8xxx_irq_set_type,
.irq_set_wake = pm8xxx_irq_set_wake,
.flags = IRQCHIP_MASK_ON_SUSPEND,
};
/**
* pm8xxx_get_irq_stat - get the status of the irq line
* @chip: pointer to identify a pmic irq controller
* @irq: the irq number
*
* The pm8xxx gpio and mpp rely on the interrupt block to read
* the values on their pins. This function is to facilitate reading
* the status of a gpio or an mpp line. The caller has to convert the
* gpio number to irq number.
*
* RETURNS:
* an int indicating the value read on that line
*/
int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
{
int pmirq, rc;
u8 block, bits, bit;
unsigned long flags;
if (chip == NULL || irq < chip->irq_base ||
irq >= chip->irq_base + chip->num_irqs)
return -EINVAL;
pmirq = irq - chip->irq_base;
block = pmirq / 8;
bit = pmirq % 8;
spin_lock_irqsave(&chip->pm_irq_lock, flags);
rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, block);
if (rc) {
pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n",
irq, pmirq, block, rc);
goto bail_out;
}
rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);
if (rc) {
pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n",
irq, pmirq, block, rc);
goto bail_out;
}
rc = (bits & (1 << bit)) ? 1 : 0;
bail_out:
spin_unlock_irqrestore(&chip->pm_irq_lock, flags);
return rc;
}
EXPORT_SYMBOL_GPL(pm8xxx_get_irq_stat);
struct pm_irq_chip * pm8xxx_irq_init(struct device *dev,
const struct pm8xxx_irq_platform_data *pdata)
{
struct pm_irq_chip *chip;
int devirq, rc;
unsigned int pmirq;
if (!pdata) {
pr_err("No platform data\n");
return ERR_PTR(-EINVAL);
}
devirq = pdata->devirq;
if (devirq < 0) {
pr_err("missing devirq\n");
rc = devirq;
return ERR_PTR(-EINVAL);
}
chip = kzalloc(sizeof(struct pm_irq_chip)
+ sizeof(u8) * pdata->irq_cdata.nirqs, GFP_KERNEL);
if (!chip) {
pr_err("Cannot alloc pm_irq_chip struct\n");
return ERR_PTR(-EINVAL);
}
chip->dev = dev;
chip->devirq = devirq;
chip->irq_base = pdata->irq_base;
chip->num_irqs = pdata->irq_cdata.nirqs;
chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
spin_lock_init(&chip->pm_irq_lock);
for (pmirq = 0; pmirq < chip->num_irqs; pmirq++) {
irq_set_chip_and_handler(chip->irq_base + pmirq,
&pm8xxx_irq_chip,
handle_level_irq);
irq_set_chip_data(chip->irq_base + pmirq, chip);
#ifdef CONFIG_ARM
set_irq_flags(chip->irq_base + pmirq, IRQF_VALID);
#else
irq_set_noprobe(chip->irq_base + pmirq);
#endif
}
irq_set_irq_type(devirq, pdata->irq_trigger_flag);
irq_set_handler_data(devirq, chip);
irq_set_chained_handler(devirq, pm8xxx_irq_handler);
set_irq_wake(devirq, 1);
return chip;
}
int pm8xxx_irq_exit(struct pm_irq_chip *chip)
{
irq_set_chained_handler(chip->devirq, NULL);
kfree(chip);
return 0;
}
......@@ -22,7 +22,6 @@
*/
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/mfd/rc5t583.h>
......
......@@ -19,7 +19,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
......
......@@ -19,7 +19,6 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/module.h>
......
This diff is collapsed.
......@@ -60,6 +60,7 @@ static const struct mfd_cell s5m8767_devs[] = {
.name = "s5m-rtc",
}, {
.name = "s5m8767-clk",
.of_compatible = "samsung,s5m8767-clk",
}
};
......@@ -68,6 +69,7 @@ static const struct mfd_cell s2mps11_devs[] = {
.name = "s2mps11-pmic",
}, {
.name = "s2mps11-clk",
.of_compatible = "samsung,s2mps11-clk",
}
};
......@@ -78,6 +80,7 @@ static const struct mfd_cell s2mps14_devs[] = {
.name = "s2mps14-rtc",
}, {
.name = "s2mps14-clk",
.of_compatible = "samsung,s2mps14-clk",
}
};
......@@ -295,6 +298,13 @@ static int sec_pmic_probe(struct i2c_client *i2c,
switch (sec_pmic->device_type) {
case S2MPA01:
regmap = &s2mpa01_regmap_config;
/*
* The rtc-s5m driver does not support S2MPA01 and there
* is no mfd_cell for S2MPA01 RTC device.
* However we must pass something to devm_regmap_init_i2c()
* so use S5M-like regmap config even though it wouldn't work.
*/
regmap_rtc = &s5m_rtc_regmap_config;
break;
case S2MPS11X:
regmap = &s2mps11_regmap_config;
......@@ -344,7 +354,7 @@ static int sec_pmic_probe(struct i2c_client *i2c,
ret = PTR_ERR(sec_pmic->regmap_rtc);
dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n",
ret);
return ret;
goto err_regmap_rtc;
}
if (pdata && pdata->cfg_pmic_irq)
......@@ -385,14 +395,15 @@ static int sec_pmic_probe(struct i2c_client *i2c,
}
if (ret)
goto err;
goto err_mfd;
device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
return ret;
err:
err_mfd:
sec_irq_exit(sec_pmic);
err_regmap_rtc:
i2c_unregister_device(sec_pmic->rtc);
return ret;
}
......
......@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
......
......@@ -706,7 +706,7 @@ static int stmpe1801_reset(struct stmpe *stmpe)
if (!(ret & STMPE1801_MSK_SYS_CTRL_RESET))
return 0;
usleep_range(100, 200);
};
}
return -EIO;
}
......
......@@ -167,7 +167,7 @@ static struct mfd_cell stw481x_cells[] = {
},
};
const struct regmap_config stw481x_regmap_config = {
static const struct regmap_config stw481x_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
......@@ -186,6 +186,12 @@ static int stw481x_probe(struct i2c_client *client,
i2c_set_clientdata(client, stw481x);
stw481x->client = client;
stw481x->map = devm_regmap_init_i2c(client, &stw481x_regmap_config);
if (IS_ERR(stw481x->map)) {
ret = PTR_ERR(stw481x->map);
dev_err(&client->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
}
ret = stw481x_startup(stw481x);
if (ret) {
......
......@@ -69,13 +69,6 @@ EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible);
static int syscon_match_pdevname(struct device *dev, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
const struct platform_device_id *id = platform_get_device_id(pdev);
if (id)
if (!strcmp(id->name, (const char *)data))
return 1;
return !strcmp(dev_name(dev), (const char *)data);
}
......@@ -152,7 +145,7 @@ static int syscon_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, syscon);
dev_info(dev, "regmap %pR registered\n", res);
dev_dbg(dev, "regmap %pR registered\n", res);
return 0;
}
......
......@@ -13,8 +13,10 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tc3589x.h>
#include <linux/err.h>
/**
* enum tc3589x_version - indicates the TC3589x version
......@@ -160,7 +162,7 @@ static const struct mfd_cell tc3589x_dev_gpio[] = {
.name = "tc3589x-gpio",
.num_resources = ARRAY_SIZE(gpio_resources),
.resources = &gpio_resources[0],
.of_compatible = "tc3589x-gpio",
.of_compatible = "toshiba,tc3589x-gpio",
},
};
......@@ -169,7 +171,7 @@ static const struct mfd_cell tc3589x_dev_keypad[] = {
.name = "tc3589x-keypad",
.num_resources = ARRAY_SIZE(keypad_resources),
.resources = &keypad_resources[0],
.of_compatible = "tc3589x-keypad",
.of_compatible = "toshiba,tc3589x-keypad",
},
};
......@@ -318,45 +320,74 @@ static int tc3589x_device_init(struct tc3589x *tc3589x)
return ret;
}
static int tc3589x_of_probe(struct device_node *np,
struct tc3589x_platform_data *pdata)
#ifdef CONFIG_OF
static const struct of_device_id tc3589x_match[] = {
/* Legacy compatible string */
{ .compatible = "tc3589x", .data = (void *) TC3589X_UNKNOWN },
{ .compatible = "toshiba,tc35890", .data = (void *) TC3589X_TC35890 },
{ .compatible = "toshiba,tc35892", .data = (void *) TC3589X_TC35892 },
{ .compatible = "toshiba,tc35893", .data = (void *) TC3589X_TC35893 },
{ .compatible = "toshiba,tc35894", .data = (void *) TC3589X_TC35894 },
{ .compatible = "toshiba,tc35895", .data = (void *) TC3589X_TC35895 },
{ .compatible = "toshiba,tc35896", .data = (void *) TC3589X_TC35896 },
{ }
};
MODULE_DEVICE_TABLE(of, tc3589x_match);
static struct tc3589x_platform_data *
tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
{
struct device_node *np = dev->of_node;
struct tc3589x_platform_data *pdata;
struct device_node *child;
const struct of_device_id *of_id;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return ERR_PTR(-ENOMEM);
of_id = of_match_device(tc3589x_match, dev);
if (!of_id)
return ERR_PTR(-ENODEV);
*version = (enum tc3589x_version) of_id->data;
for_each_child_of_node(np, child) {
if (!strcmp(child->name, "tc3589x_gpio")) {
if (of_device_is_compatible(child, "toshiba,tc3589x-gpio"))
pdata->block |= TC3589x_BLOCK_GPIO;
}
if (!strcmp(child->name, "tc3589x_keypad")) {
if (of_device_is_compatible(child, "toshiba,tc3589x-keypad"))
pdata->block |= TC3589x_BLOCK_KEYPAD;
}
}
return 0;
return pdata;
}
#else
static inline struct tc3589x_platform_data *
tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
{
dev_err(dev, "no device tree support\n");
return ERR_PTR(-ENODEV);
}
#endif
static int tc3589x_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct device_node *np = i2c->dev.of_node;
struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct tc3589x *tc3589x;
enum tc3589x_version version;
int ret;
if (!pdata) {
if (np) {
pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
ret = tc3589x_of_probe(np, pdata);
if (ret)
return ret;
}
else {
pdata = tc3589x_of_probe(&i2c->dev, &version);
if (IS_ERR(pdata)) {
dev_err(&i2c->dev, "No platform data or DT found\n");
return -EINVAL;
return PTR_ERR(pdata);
}
} else {
/* When not probing from device tree we have this ID */
version = id->driver_data;
}
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
......@@ -375,7 +406,7 @@ static int tc3589x_probe(struct i2c_client *i2c,
tc3589x->pdata = pdata;
tc3589x->irq_base = pdata->irq_base;
switch (id->driver_data) {
switch (version) {
case TC3589X_TC35893:
case TC3589X_TC35895:
case TC3589X_TC35896:
......@@ -471,9 +502,12 @@ static const struct i2c_device_id tc3589x_id[] = {
MODULE_DEVICE_TABLE(i2c, tc3589x_id);
static struct i2c_driver tc3589x_driver = {
.driver.name = "tc3589x",
.driver.owner = THIS_MODULE,
.driver.pm = &tc3589x_dev_pm_ops,
.driver = {
.name = "tc3589x",
.owner = THIS_MODULE,
.pm = &tc3589x_dev_pm_ops,
.of_match_table = of_match_ptr(tc3589x_match),
},
.probe = tc3589x_probe,
.remove = tc3589x_remove,
.id_table = tc3589x_id,
......
This diff is collapsed.
......@@ -14,7 +14,6 @@
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/io.h>
......@@ -184,12 +183,6 @@ static int ti_tscadc_probe(struct platform_device *pdev)
return -EINVAL;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "no memory resource defined.\n");
return -EINVAL;
}
/* Allocate memory for device */
tscadc = devm_kzalloc(&pdev->dev,
sizeof(struct ti_tscadc_dev), GFP_KERNEL);
......@@ -206,19 +199,10 @@ static int ti_tscadc_probe(struct platform_device *pdev)
} else
tscadc->irq = err;
res = devm_request_mem_region(&pdev->dev,
res->start, resource_size(res), pdev->name);
if (!res) {
dev_err(&pdev->dev, "failed to reserve registers.\n");
return -EBUSY;
}
tscadc->tscadc_base = devm_ioremap(&pdev->dev,
res->start, resource_size(res));
if (!tscadc->tscadc_base) {
dev_err(&pdev->dev, "failed to map registers.\n");
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(tscadc->tscadc_base))
return PTR_ERR(tscadc->tscadc_base);
tscadc->regmap_tscadc = devm_regmap_init_mmio(&pdev->dev,
tscadc->tscadc_base, &tscadc_regmap_config);
......
......@@ -715,7 +715,7 @@ static int timb_probe(struct pci_dev *dev,
for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
msix_entries[i].entry = i;
err = pci_enable_msix(dev, msix_entries, TIMBERDALE_NR_IRQS);
err = pci_enable_msix_exact(dev, msix_entries, TIMBERDALE_NR_IRQS);
if (err) {
dev_err(&dev->dev,
"MSI-X init failed: %d, expected entries: %d\n",
......
This diff is collapsed.
......@@ -255,8 +255,10 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
IRQF_ONESHOT, pdata->irq_base,
tps6591x_irqs_chip, &tps65910->irq_data);
if (ret < 0)
if (ret < 0) {
dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret);
tps65910->chip_irq = 0;
}
return ret;
}
......@@ -509,6 +511,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
regmap_irq_get_domain(tps65910->irq_data));
if (ret < 0) {
dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
tps65910_irq_exit(tps65910);
return ret;
}
......
......@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/mfd/core.h>
......
......@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bug.h>
#include <linux/device.h>
#include <linux/interrupt.h>
......
......@@ -282,11 +282,11 @@ static struct reg_default twl4030_49_defaults[] = {
static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case 0:
case 3:
case 40:
case 41:
case 42:
case 0x00:
case 0x03:
case 0x40:
case 0x41:
case 0x42:
return false;
default:
return true;
......
......@@ -27,7 +27,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
......
......@@ -31,7 +31,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
......
......@@ -661,6 +661,11 @@ static int twl6040_probe(struct i2c_client *client,
init_completion(&twl6040->ready);
twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
if (twl6040->rev < 0) {
dev_err(&client->dev, "Failed to read revision register: %d\n",
twl6040->rev);
goto gpio_err;
}
/* ERRATA: Automatic power-up is not possible in ES1.0 */
if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
......@@ -703,7 +708,6 @@ static int twl6040_probe(struct i2c_client *client,
}
/* dual-access registers controlled by I2C only */
twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL);
regmap_register_patch(twl6040->regmap, twl6040_patch,
ARRAY_SIZE(twl6040_patch));
......
......@@ -742,9 +742,7 @@ static int ucb1x00_resume(struct device *dev)
}
#endif
static const struct dev_pm_ops ucb1x00_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume)
};
static SIMPLE_DEV_PM_OPS(ucb1x00_pm_ops, ucb1x00_suspend, ucb1x00_resume);
static struct mcp_driver ucb1x00_driver = {
.drv = {
......
......@@ -16,7 +16,6 @@
#include <linux/bitops.h>
#include <linux/completion.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/of_device.h>
......@@ -27,7 +26,7 @@
#define VEXPRESS_CONFIG_MAX_BRIDGES 2
struct vexpress_config_bridge {
static struct vexpress_config_bridge {
struct device_node *node;
struct vexpress_config_bridge_info *info;
struct list_head transactions;
......
......@@ -168,7 +168,7 @@ static void *vexpress_sysreg_config_func_get(struct device *dev,
struct device_node *node)
{
struct vexpress_sysreg_config_func *config_func;
u32 site;
u32 site = 0;
u32 position = 0;
u32 dcc = 0;
u32 func_device[2];
......
......@@ -73,6 +73,7 @@ static const struct reg_default wm5102_revb_patch[] = {
{ 0x171, 0x0000 },
{ 0x35E, 0x000C },
{ 0x2D4, 0x0000 },
{ 0x4DC, 0x0900 },
{ 0x80, 0x0000 },
};
......@@ -1839,6 +1840,23 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_DSP1_STATUS_1:
case ARIZONA_DSP1_STATUS_2:
case ARIZONA_DSP1_STATUS_3:
case ARIZONA_DSP1_WDMA_BUFFER_1:
case ARIZONA_DSP1_WDMA_BUFFER_2:
case ARIZONA_DSP1_WDMA_BUFFER_3:
case ARIZONA_DSP1_WDMA_BUFFER_4:
case ARIZONA_DSP1_WDMA_BUFFER_5:
case ARIZONA_DSP1_WDMA_BUFFER_6:
case ARIZONA_DSP1_WDMA_BUFFER_7:
case ARIZONA_DSP1_WDMA_BUFFER_8:
case ARIZONA_DSP1_RDMA_BUFFER_1:
case ARIZONA_DSP1_RDMA_BUFFER_2:
case ARIZONA_DSP1_RDMA_BUFFER_3:
case ARIZONA_DSP1_RDMA_BUFFER_4:
case ARIZONA_DSP1_RDMA_BUFFER_5:
case ARIZONA_DSP1_RDMA_BUFFER_6:
case ARIZONA_DSP1_WDMA_CONFIG_1:
case ARIZONA_DSP1_WDMA_CONFIG_2:
case ARIZONA_DSP1_RDMA_CONFIG_1:
case ARIZONA_DSP1_SCRATCH_0:
case ARIZONA_DSP1_SCRATCH_1:
case ARIZONA_DSP1_SCRATCH_2:
......@@ -1894,9 +1912,27 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
case ARIZONA_AOD_IRQ1:
case ARIZONA_AOD_IRQ2:
case ARIZONA_AOD_IRQ_RAW_STATUS:
case ARIZONA_DSP1_CLOCKING_1:
case ARIZONA_DSP1_STATUS_1:
case ARIZONA_DSP1_STATUS_2:
case ARIZONA_DSP1_STATUS_3:
case ARIZONA_DSP1_WDMA_BUFFER_1:
case ARIZONA_DSP1_WDMA_BUFFER_2:
case ARIZONA_DSP1_WDMA_BUFFER_3:
case ARIZONA_DSP1_WDMA_BUFFER_4:
case ARIZONA_DSP1_WDMA_BUFFER_5:
case ARIZONA_DSP1_WDMA_BUFFER_6:
case ARIZONA_DSP1_WDMA_BUFFER_7:
case ARIZONA_DSP1_WDMA_BUFFER_8:
case ARIZONA_DSP1_RDMA_BUFFER_1:
case ARIZONA_DSP1_RDMA_BUFFER_2:
case ARIZONA_DSP1_RDMA_BUFFER_3:
case ARIZONA_DSP1_RDMA_BUFFER_4:
case ARIZONA_DSP1_RDMA_BUFFER_5:
case ARIZONA_DSP1_RDMA_BUFFER_6:
case ARIZONA_DSP1_WDMA_CONFIG_1:
case ARIZONA_DSP1_WDMA_CONFIG_2:
case ARIZONA_DSP1_RDMA_CONFIG_1:
case ARIZONA_DSP1_SCRATCH_0:
case ARIZONA_DSP1_SCRATCH_1:
case ARIZONA_DSP1_SCRATCH_2:
......
This diff is collapsed.
......@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/bug.h>
#include <linux/device.h>
......
......@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bug.h>
#include <linux/device.h>
#include <linux/interrupt.h>
......
......@@ -161,31 +161,19 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8400 *wm8400;
int ret;
wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL);
if (wm8400 == NULL) {
ret = -ENOMEM;
goto err;
}
if (!wm8400)
return -ENOMEM;
wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config);
if (IS_ERR(wm8400->regmap)) {
ret = PTR_ERR(wm8400->regmap);
goto err;
}
if (IS_ERR(wm8400->regmap))
return PTR_ERR(wm8400->regmap);
wm8400->dev = &i2c->dev;
i2c_set_clientdata(i2c, wm8400);
ret = wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
if (ret != 0)
goto err;
return 0;
err:
return ret;
return wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
}
static int wm8400_i2c_remove(struct i2c_client *i2c)
......
This diff is collapsed.
......@@ -195,6 +195,18 @@ static inline int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg) {
return twl_i2c_read(mod_no, val, reg, 1);
}
static inline int twl_i2c_write_u16(u8 mod_no, u16 val, u8 reg) {
val = cpu_to_le16(val);
return twl_i2c_write(mod_no, (u8*) &val, reg, 2);
}
static inline int twl_i2c_read_u16(u8 mod_no, u16 *val, u8 reg) {
int ret;
ret = twl_i2c_read(mod_no, (u8*) val, reg, 2);
*val = le16_to_cpu(*val);
return ret;
}
int twl_get_type(void);
int twl_get_version(void);
int twl_get_hfclk_rate(void);
......
......@@ -44,7 +44,7 @@ struct twl4030_madc_conversion_method {
struct twl4030_madc_request {
unsigned long channels;
u16 do_avg;
bool do_avg;
u16 method;
u16 type;
bool active;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment