Resync master with latest Linus upstream

This commit is contained in:
Andrew Morton 2022-12-17 20:39:52 -08:00
commit b29e6ece45
91 changed files with 1248 additions and 911 deletions

View File

@ -100,6 +100,7 @@ properties:
- pattern
# LED is triggered by SD/MMC activity
- pattern: "^mmc[0-9]+$"
- pattern: "^cpu[0-9]*$"
led-pattern:
description: |

View File

@ -1,67 +0,0 @@
Qualcomm PM8058 LED driver
The Qualcomm PM8058 is a multi-functional device which contains
an LED driver block for up to six LEDs: three normal LEDs, two
"flash" LEDs and one "keypad backlight" LED. The names are
quoted because sometimes these LED drivers are used for wildly
different things than flash or keypad backlight: their names
are more of a suggestion than a hard-wired usecase.
Hardware-wise the different LEDs support slightly different
output currents. The "flash" LEDs do not need to charge nor
do they support external triggers. They are just powerful LED
drivers.
The LEDs appear as children to the PM8058 device, with the
proper compatible string. For the PM8058 bindings see:
mfd/qcom-pm8xxx.txt.
Each LED is represented as a sub-node of the syscon device. Each
node's name represents the name of the corresponding LED.
LED sub-node properties:
Required properties:
- compatible: one of
"qcom,pm8058-led" (for the normal LEDs at 0x131, 0x132 and 0x133)
"qcom,pm8058-keypad-led" (for the "keypad" LED at 0x48)
"qcom,pm8058-flash-led" (for the "flash" LEDs at 0x49 and 0xFB)
Optional properties:
- label: see Documentation/devicetree/bindings/leds/common.txt
- default-state: see Documentation/devicetree/bindings/leds/common.txt
- linux,default-trigger: see Documentation/devicetree/bindings/leds/common.txt
Example:
qcom,ssbi@500000 {
pmicintc: pmic@0 {
compatible = "qcom,pm8058";
led@48 {
compatible = "qcom,pm8058-keypad-led";
reg = <0x48>;
label = "pm8050:white:keypad";
default-state = "off";
};
led@131 {
compatible = "qcom,pm8058-led";
reg = <0x131>;
label = "pm8058:red";
default-state = "off";
};
led@132 {
compatible = "qcom,pm8058-led";
reg = <0x132>;
label = "pm8058:yellow";
default-state = "off";
linux,default-trigger = "mmc0";
};
led@133 {
compatible = "qcom,pm8058-led";
reg = <0x133>;
label = "pm8058:green";
default-state = "on";
linux,default-trigger = "heartbeat";
};
};
};

View File

@ -0,0 +1,57 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/leds/qcom,pm8058-led.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm PM8058 PMIC LED
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
description: |
The Qualcomm PM8058 contains an LED block for up to six LEDs:: three normal
LEDs, two "flash" LEDs and one "keypad backlight" LED. The names are quoted
because sometimes these LED drivers are used for wildly different things than
flash or keypad backlight:: their names are more of a suggestion than a
hard-wired usecase.
Hardware-wise the different LEDs support slightly different output currents.
The "flash" LEDs do not need to charge nor do they support external triggers.
They are just powerful LED drivers.
allOf:
- $ref: common.yaml#
properties:
compatible:
enum:
- qcom,pm8058-led
- qcom,pm8058-keypad-led
- qcom,pm8058-flash-led
reg:
maxItems: 1
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/leds/common.h>
pmic {
#address-cells = <1>;
#size-cells = <0>;
led@131 {
compatible = "qcom,pm8058-led";
reg = <0x131>;
label = "pm8058:red";
color = <LED_COLOR_ID_RED>;
default-state = "off";
};
};

View File

@ -13,6 +13,8 @@ description: |
maintainers:
- Dmitry Osipenko <digetx@gmail.com>
$ref: /schemas/power/supply/power-supply.yaml
properties:
compatible:
items:
@ -22,15 +24,13 @@ properties:
reg:
maxItems: 1
monitored-battery: true
power-supplies: true
system-power-controller: true
required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |

View File

@ -39,6 +39,10 @@ properties:
interrupt-controller: true
patternProperties:
"led@[0-9a-f]+$":
type: object
$ref: /schemas/leds/qcom,pm8058-led.yaml#
"rtc@[0-9a-f]+$":
type: object
$ref: "../rtc/qcom-pm8xxx-rtc.yaml"

View File

@ -124,6 +124,8 @@ properties:
The child node for the charger to hold additional properties. If a
battery is not in use, this node can be omitted.
type: object
$ref: /schemas/power/supply/power-supply.yaml
properties:
monitored-battery:
description: |

View File

@ -25,6 +25,9 @@ description: >
inactive-delay, the GPIO is driven active again. After a delay specified by wait-delay, the
restart handler completes allowing other restart handlers to be attempted.
allOf:
- $ref: restart-handler.yaml#
properties:
compatible:
const: gpio-restart
@ -41,16 +44,6 @@ properties:
in its inactive state.
priority:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
A priority ranging from 0 to 255 (default 129) according to the following guidelines:
0: Restart handler of last resort, with limited restart capabilities.
128: Default restart handler; use if no other restart handler is expected to be available,
and/or if restart functionality is sufficient to restart the entire system.
255: Highest priority restart handler, will preempt all other restart handlers.
minimum: 0
maximum: 255
default: 129
active-delay:

View File

@ -0,0 +1,30 @@
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/power/reset/restart-handler.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Restart and shutdown handler generic binding
maintainers:
- Sebastian Reichel <sre@kernel.org>
description:
Restart and shutdown handler device is responsible for powering off the
system, e.g. my cutting off the power. System might have several restart
handlers, which usually are tried from most precise to last resort.
properties:
priority:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
A priority ranging from 0 to 255 according to the following guidelines::
0:: Restart handler of last resort, with limited restart capabilities.
128:: Typical, default restart handler; use if no other restart handler
is expected to be available, and/or if restart functionality is
sufficient to restart the entire system.
255:: Highest priority restart handler, will preempt all other restart handlers.
minimum: 0
maximum: 255
additionalProperties: true

View File

@ -15,11 +15,15 @@ allOf:
properties:
compatible:
enum:
- ti,bq25890
- ti,bq25892
- ti,bq25895
- ti,bq25896
oneOf:
- enum:
- ti,bq25890
- items:
- enum:
- ti,bq25892
- ti,bq25895
- ti,bq25896
- const: ti,bq25890
reg:
maxItems: 1
@ -93,7 +97,7 @@ required:
- ti,boost-voltage
- ti,boost-max-current
additionalProperties: false
unevaluatedProperties: false
examples:
- |

View File

@ -60,13 +60,11 @@ properties:
monitored-battery:
description: |
phandle of battery characteristics node.
The fuel gauge uses the following battery properties:
- energy-full-design-microwatt-hours
- charge-full-design-microamp-hours
- voltage-min-design-microvolt
Both or neither of the *-full-design-*-hours properties must be set.
See Documentation/devicetree/bindings/power/supply/battery.yaml
power-supplies: true

View File

@ -10,6 +10,8 @@ title: Ingenic JZ47xx battery bindings
maintainers:
- Artur Rojek <contact@artur-rojek.eu>
$ref: power-supply.yaml#
properties:
compatible:
oneOf:
@ -28,8 +30,6 @@ properties:
monitored-battery:
description: >
phandle to a "simple-battery" compatible node.
This property must be a phandle to a node using the format described
in battery.yaml, with the following properties being required:
- voltage-min-design-microvolt: drained battery voltage,

View File

@ -59,6 +59,8 @@ properties:
Voltage threshold to report battery as over voltage (in mV).
Default is not to report over-voltage events.
power-supplies: true
required:
- compatible
- reg

View File

@ -18,4 +18,10 @@ properties:
This property is added to a supply in order to list the devices which
supply it power, referenced by their phandles.
monitored-battery:
$ref: /schemas/types.yaml#/definitions/phandle
description:
The battery (with "simple-battery" compatible) being monitored by this
power supply.
additionalProperties: true

View File

@ -18,6 +18,7 @@ description: |
provides a Dual-source Battery Charger, two port BC1.2 detection and a
Battery Monitor.
$ref: power-supply.yaml#
properties:
compatible:

View File

@ -28,7 +28,6 @@ properties:
The charger uses the following battery properties
- charge-term-current-microamp: current for charge termination phase.
- constant-charge-voltage-max-microvolt: maximum constant input voltage.
See Documentation/devicetree/bindings/power/supply/battery.yaml
additionalProperties: false

View File

@ -0,0 +1,80 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/watchdog/mediatek,mtk-wdt.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek SoCs Watchdog timer
maintainers:
- Matthias Brugger <matthias.bgg@gmail.com>
description:
The watchdog supports a pre-timeout interrupt that fires
timeout-sec/2 before the expiry.
allOf:
- $ref: watchdog.yaml#
properties:
compatible:
oneOf:
- enum:
- mediatek,mt2712-wdt
- mediatek,mt6589-wdt
- mediatek,mt6795-wdt
- mediatek,mt7986-wdt
- mediatek,mt8183-wdt
- mediatek,mt8186-wdt
- mediatek,mt8188-wdt
- mediatek,mt8192-wdt
- mediatek,mt8195-wdt
- items:
- enum:
- mediatek,mt2701-wdt
- mediatek,mt6582-wdt
- mediatek,mt6797-wdt
- mediatek,mt7622-wdt
- mediatek,mt7623-wdt
- mediatek,mt7629-wdt
- mediatek,mt8173-wdt
- mediatek,mt8516-wdt
- const: mediatek,mt6589-wdt
reg:
maxItems: 1
interrupts:
items:
- description: Watchdog pre-timeout (bark) interrupt
mediatek,disable-extrst:
description: Disable sending output reset signal
type: boolean
'#reset-cells':
const: 1
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
watchdog: watchdog@10007000 {
compatible = "mediatek,mt8183-wdt";
reg = <0 0x10007000 0 0x100>;
interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_LOW>;
mediatek,disable-extrst;
timeout-sec = <10>;
#reset-cells = <1>;
};
};

View File

@ -1,42 +0,0 @@
Mediatek SoCs Watchdog timer
The watchdog supports a pre-timeout interrupt that fires timeout-sec/2
before the expiry.
Required properties:
- compatible should contain:
"mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701
"mediatek,mt2712-wdt": for MT2712
"mediatek,mt6582-wdt", "mediatek,mt6589-wdt": for MT6582
"mediatek,mt6589-wdt": for MT6589
"mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797
"mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
"mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623
"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
"mediatek,mt7986-wdt", "mediatek,mt6589-wdt": for MT7986
"mediatek,mt8183-wdt": for MT8183
"mediatek,mt8186-wdt", "mediatek,mt6589-wdt": for MT8186
"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
"mediatek,mt8192-wdt": for MT8192
"mediatek,mt8195-wdt", "mediatek,mt6589-wdt": for MT8195
- reg : Specifies base physical address and size of the registers.
Optional properties:
- mediatek,disable-extrst: disable send output reset signal
- interrupts: Watchdog pre-timeout (bark) interrupt.
- timeout-sec: contains the watchdog timeout in seconds.
- #reset-cells: Should be 1.
Example:
watchdog: watchdog@10007000 {
compatible = "mediatek,mt8183-wdt",
"mediatek,mt6589-wdt";
mediatek,disable-extrst;
reg = <0 0x10007000 0 0x100>;
interrupts = <GIC_SPI 139 IRQ_TYPE_NONE>;
timeout-sec = <10>;
#reset-cells = <1>;
};

View File

@ -11732,11 +11732,13 @@ F: scripts/leaking_addresses.pl
LED SUBSYSTEM
M: Pavel Machek <pavel@ucw.cz>
M: Lee Jones <lee@kernel.org>
L: linux-leds@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git
F: Documentation/devicetree/bindings/leds/
F: drivers/leds/
F: include/dt-bindings/leds/
F: include/linux/leds.h
LEGACY EEPROM DRIVER

View File

@ -968,7 +968,7 @@ static void ssip_xmit_work(struct work_struct *work)
ssip_xmit(cl);
}
static int ssip_pn_xmit(struct sk_buff *skb, struct net_device *dev)
static netdev_tx_t ssip_pn_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct hsi_client *cl = to_hsi_client(dev->dev.parent);
struct ssi_protocol *ssi = hsi_client_drvdata(cl);
@ -1027,7 +1027,7 @@ static int ssip_pn_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
return 0;
return NETDEV_TX_OK;
drop2:
hsi_free_msg(msg);
drop:
@ -1035,7 +1035,7 @@ drop:
inc_dropped:
dev->stats.tx_dropped++;
return 0;
return NETDEV_TX_OK;
}
/* CMT reset event handler */

View File

@ -502,8 +502,10 @@ static int ssi_probe(struct platform_device *pd)
platform_set_drvdata(pd, ssi);
err = ssi_add_controller(ssi, pd);
if (err < 0)
if (err < 0) {
hsi_put_controller(ssi);
goto out1;
}
pm_runtime_enable(&pd->dev);
@ -536,9 +538,9 @@ out3:
device_for_each_child(&pd->dev, NULL, ssi_remove_ports);
out2:
ssi_remove_controller(ssi);
pm_runtime_disable(&pd->dev);
out1:
platform_set_drvdata(pd, NULL);
pm_runtime_disable(&pd->dev);
return err;
}
@ -629,7 +631,13 @@ static int __init ssi_init(void) {
if (ret)
return ret;
return platform_driver_register(&ssi_port_pdriver);
ret = platform_driver_register(&ssi_port_pdriver);
if (ret) {
platform_driver_unregister(&ssi_pdriver);
return ret;
}
return 0;
}
module_init(ssi_init);

View File

@ -785,53 +785,61 @@ out:
return ret;
}
static enum resp_states atomic_write_reply(struct rxe_qp *qp,
struct rxe_pkt_info *pkt)
#ifdef CONFIG_64BIT
static enum resp_states do_atomic_write(struct rxe_qp *qp,
struct rxe_pkt_info *pkt)
{
u64 src, *dst;
struct resp_res *res = qp->resp.res;
struct rxe_mr *mr = qp->resp.mr;
int payload = payload_size(pkt);
u64 src, *dst;
if (mr->state != RXE_MR_STATE_VALID)
return RESPST_ERR_RKEY_VIOLATION;
memcpy(&src, payload_addr(pkt), payload);
dst = iova_to_vaddr(mr, qp->resp.va + qp->resp.offset, payload);
/* check vaddr is 8 bytes aligned. */
if (!dst || (uintptr_t)dst & 7)
return RESPST_ERR_MISALIGNED_ATOMIC;
/* Do atomic write after all prior operations have completed */
smp_store_release(dst, src);
/* decrease resp.resid to zero */
qp->resp.resid -= sizeof(payload);
qp->resp.msn++;
/* next expected psn, read handles this separately */
qp->resp.psn = (pkt->psn + 1) & BTH_PSN_MASK;
qp->resp.ack_psn = qp->resp.psn;
qp->resp.opcode = pkt->opcode;
qp->resp.status = IB_WC_SUCCESS;
return RESPST_ACKNOWLEDGE;
}
#else
static enum resp_states do_atomic_write(struct rxe_qp *qp,
struct rxe_pkt_info *pkt)
{
return RESPST_ERR_UNSUPPORTED_OPCODE;
}
#endif /* CONFIG_64BIT */
static enum resp_states atomic_write_reply(struct rxe_qp *qp,
struct rxe_pkt_info *pkt)
{
struct resp_res *res = qp->resp.res;
if (!res) {
res = rxe_prepare_res(qp, pkt, RXE_ATOMIC_WRITE_MASK);
qp->resp.res = res;
}
if (!res->replay) {
#ifdef CONFIG_64BIT
if (mr->state != RXE_MR_STATE_VALID)
return RESPST_ERR_RKEY_VIOLATION;
memcpy(&src, payload_addr(pkt), payload);
dst = iova_to_vaddr(mr, qp->resp.va + qp->resp.offset, payload);
/* check vaddr is 8 bytes aligned. */
if (!dst || (uintptr_t)dst & 7)
return RESPST_ERR_MISALIGNED_ATOMIC;
/* Do atomic write after all prior operations have completed */
smp_store_release(dst, src);
/* decrease resp.resid to zero */
qp->resp.resid -= sizeof(payload);
qp->resp.msn++;
/* next expected psn, read handles this separately */
qp->resp.psn = (pkt->psn + 1) & BTH_PSN_MASK;
qp->resp.ack_psn = qp->resp.psn;
qp->resp.opcode = pkt->opcode;
qp->resp.status = IB_WC_SUCCESS;
if (res->replay)
return RESPST_ACKNOWLEDGE;
#else
return RESPST_ERR_UNSUPPORTED_OPCODE;
#endif /* CONFIG_64BIT */
}
return RESPST_ACKNOWLEDGE;
return do_atomic_write(qp, pkt);
}
static struct sk_buff *prepare_ack_packet(struct rxe_qp *qp,

View File

@ -29,7 +29,7 @@ static struct page *siw_get_pblpage(struct siw_mem *mem, u64 addr, int *idx)
dma_addr_t paddr = siw_pbl_get_buffer(pbl, offset, NULL, idx);
if (paddr)
return virt_to_page((void *)paddr);
return virt_to_page((void *)(uintptr_t)paddr);
return NULL;
}

View File

@ -139,11 +139,11 @@ static ssize_t show_color_common(struct device *dev, char *buf, int color)
return ret;
switch (color) {
case RED:
return scnprintf(buf, PAGE_SIZE, "%02X\n", data->red);
return sysfs_emit(buf, "%02X\n", data->red);
case GREEN:
return scnprintf(buf, PAGE_SIZE, "%02X\n", data->green);
return sysfs_emit(buf, "%02X\n", data->green);
case BLUE:
return scnprintf(buf, PAGE_SIZE, "%02X\n", data->blue);
return sysfs_emit(buf, "%02X\n", data->blue);
default:
return -EINVAL;
}
@ -253,7 +253,7 @@ static DEVICE_ATTR_RW(blue);
static ssize_t test_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return scnprintf(buf, PAGE_SIZE,
return sysfs_emit(buf,
"#Write into test to start test sequence!#\n");
}

View File

@ -38,6 +38,7 @@
#define IS31FL3190_CURRENT_uA_MIN 5000
#define IS31FL3190_CURRENT_uA_DEFAULT 42000
#define IS31FL3190_CURRENT_uA_MAX 42000
#define IS31FL3190_CURRENT_SHIFT 2
#define IS31FL3190_CURRENT_MASK GENMASK(4, 2)
#define IS31FL3190_CURRENT_5_mA 0x02
#define IS31FL3190_CURRENT_10_mA 0x01
@ -553,7 +554,7 @@ static int is31fl319x_probe(struct i2c_client *client)
is31fl3196_db_to_gain(is31->audio_gain_db));
else
regmap_update_bits(is31->regmap, IS31FL3190_CURRENT, IS31FL3190_CURRENT_MASK,
is31fl3190_microamp_to_cs(dev, aggregated_led_microamp));
is31fl3190_microamp_to_cs(dev, aggregated_led_microamp) << IS31FL3190_CURRENT_SHIFT);
for (i = 0; i < is31->cdef->num_leds; i++) {
struct is31fl319x_led *led = &is31->leds[i];

View File

@ -314,7 +314,7 @@ static ssize_t show_id(struct device *dev,
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct lm3533_led *led = to_lm3533_led(led_cdev);
return scnprintf(buf, PAGE_SIZE, "%d\n", led->id);
return sysfs_emit(buf, "%d\n", led->id);
}
/*
@ -344,7 +344,7 @@ static ssize_t show_risefalltime(struct device *dev,
if (ret)
return ret;
return scnprintf(buf, PAGE_SIZE, "%x\n", val);
return sysfs_emit(buf, "%x\n", val);
}
static ssize_t show_risetime(struct device *dev,
@ -415,7 +415,7 @@ static ssize_t show_als_channel(struct device *dev,
channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1;
return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
return sysfs_emit(buf, "%u\n", channel);
}
static ssize_t store_als_channel(struct device *dev,
@ -465,7 +465,7 @@ static ssize_t show_als_en(struct device *dev,
enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
return sysfs_emit(buf, "%d\n", enable);
}
static ssize_t store_als_en(struct device *dev,
@ -518,7 +518,7 @@ static ssize_t show_linear(struct device *dev,
else
linear = 0;
return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
return sysfs_emit(buf, "%x\n", linear);
}
static ssize_t store_linear(struct device *dev,
@ -564,7 +564,7 @@ static ssize_t show_pwm(struct device *dev,
if (ret)
return ret;
return scnprintf(buf, PAGE_SIZE, "%u\n", val);
return sysfs_emit(buf, "%u\n", val);
}
static ssize_t store_pwm(struct device *dev,

View File

@ -469,7 +469,7 @@ static ssize_t lp5521_selftest(struct device *dev,
ret = lp5521_run_selftest(chip, buf);
mutex_unlock(&chip->lock);
return scnprintf(buf, PAGE_SIZE, "%s\n", ret ? "FAIL" : "OK");
return sysfs_emit(buf, "%s\n", ret ? "FAIL" : "OK");
}
/* device attributes */

View File

@ -581,8 +581,8 @@ static ssize_t lp5523_selftest(struct device *dev,
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
struct lp55xx_chip *chip = led->chip;
struct lp55xx_platform_data *pdata = chip->pdata;
int i, ret, pos = 0;
u8 status, adc, vdd;
int ret, pos = 0;
u8 status, adc, vdd, i;
mutex_lock(&chip->lock);
@ -612,20 +612,21 @@ static ssize_t lp5523_selftest(struct device *dev,
vdd--; /* There may be some fluctuation in measurement */
for (i = 0; i < LP5523_MAX_LEDS; i++) {
/* Skip non-existing channels */
for (i = 0; i < pdata->num_channels; i++) {
/* Skip disabled channels */
if (pdata->led_config[i].led_current == 0)
continue;
/* Set default current */
lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
pdata->led_config[i].led_current);
lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0xff);
lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr,
0xff);
/* let current stabilize 2 - 4ms before measurements start */
usleep_range(2000, 4000);
lp55xx_write(chip, LP5523_REG_LED_TEST_CTRL,
LP5523_EN_LEDTEST | i);
LP5523_EN_LEDTEST | led->chan_nr);
/* ADC conversion time is 2.7 ms typically */
usleep_range(3000, 6000);
ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
@ -633,20 +634,22 @@ static ssize_t lp5523_selftest(struct device *dev,
goto fail;
if (!(status & LP5523_LEDTEST_DONE))
usleep_range(3000, 6000);/* Was not ready. Wait. */
usleep_range(3000, 6000); /* Was not ready. Wait. */
ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &adc);
if (ret < 0)
goto fail;
if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
pos += sprintf(buf + pos, "LED %d FAIL\n", i);
pos += sprintf(buf + pos, "LED %d FAIL\n",
led->chan_nr);
lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0x00);
lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr,
0x00);
/* Restore current */
lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
led->led_current);
lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
led->led_current);
led++;
}
if (pos == 0)

View File

@ -88,7 +88,7 @@ static ssize_t led_current_show(struct device *dev,
{
struct lp55xx_led *led = dev_to_lp55xx_led(dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", led->led_current);
return sysfs_emit(buf, "%d\n", led->led_current);
}
static ssize_t led_current_store(struct device *dev,
@ -121,7 +121,7 @@ static ssize_t max_current_show(struct device *dev,
{
struct lp55xx_led *led = dev_to_lp55xx_led(dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", led->max_current);
return sysfs_emit(buf, "%d\n", led->max_current);
}
static DEVICE_ATTR_RW(led_current);
@ -166,7 +166,7 @@ static int lp55xx_init_led(struct lp55xx_led *led,
struct mc_subled *mc_led_info;
struct led_classdev *led_cdev;
char name[32];
int i, j = 0;
int i;
int ret;
if (chan >= max_channel) {
@ -201,7 +201,6 @@ static int lp55xx_init_led(struct lp55xx_led *led,
pdata->led_config[chan].color_id[i];
mc_led_info[i].channel =
pdata->led_config[chan].output_num[i];
j++;
}
led->mc_cdev.subled_info = mc_led_info;

View File

@ -238,11 +238,6 @@ static int max8997_led_probe(struct platform_device *pdev)
char name[20];
int ret = 0;
if (pdata == NULL) {
dev_err(&pdev->dev, "no platform data\n");
return -ENODEV;
}
led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
if (led == NULL)
return -ENOMEM;
@ -258,7 +253,7 @@ static int max8997_led_probe(struct platform_device *pdev)
led->iodev = iodev;
/* initialize mode and brightness according to platform_data */
if (pdata->led_pdata) {
if (pdata && pdata->led_pdata) {
u8 mode = 0, brightness = 0;
mode = pdata->led_pdata->mode[led->id];

View File

@ -145,12 +145,6 @@ static inline int pca95xx_num_input_regs(int bits)
return (bits + 7) / 8;
}
/* 4 bits per LED selector register */
static inline int pca95xx_num_led_regs(int bits)
{
return (bits + 3) / 4;
}
/*
* Return an LED selector register value based on an existing one, with
* the appropriate 2-bit state value set for the given LED number (0-3).

View File

@ -602,8 +602,8 @@ static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
lpg_lut_sync(lpg, lut_mask);
}
static void lpg_brightness_single_set(struct led_classdev *cdev,
enum led_brightness value)
static int lpg_brightness_single_set(struct led_classdev *cdev,
enum led_brightness value)
{
struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
struct mc_subled info;
@ -614,10 +614,12 @@ static void lpg_brightness_single_set(struct led_classdev *cdev,
lpg_brightness_set(led, cdev, &info);
mutex_unlock(&led->lpg->lock);
return 0;
}
static void lpg_brightness_mc_set(struct led_classdev *cdev,
enum led_brightness value)
static int lpg_brightness_mc_set(struct led_classdev *cdev,
enum led_brightness value)
{
struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
@ -628,6 +630,8 @@ static void lpg_brightness_mc_set(struct led_classdev *cdev,
lpg_brightness_set(led, cdev, mc->subled_info);
mutex_unlock(&led->lpg->lock);
return 0;
}
static int lpg_blink_set(struct lpg_led *led,
@ -1118,7 +1122,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
led->mcdev.num_colors = num_channels;
cdev = &led->mcdev.led_cdev;
cdev->brightness_set = lpg_brightness_mc_set;
cdev->brightness_set_blocking = lpg_brightness_mc_set;
cdev->blink_set = lpg_blink_mc_set;
/* Register pattern accessors only if we have a LUT block */
@ -1132,7 +1136,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
return ret;
cdev = &led->cdev;
cdev->brightness_set = lpg_brightness_single_set;
cdev->brightness_set_blocking = lpg_brightness_single_set;
cdev->blink_set = lpg_blink_single_set;
/* Register pattern accessors only if we have a LUT block */
@ -1151,7 +1155,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
else
cdev->brightness = LED_OFF;
cdev->brightness_set(cdev, cdev->brightness);
cdev->brightness_set_blocking(cdev, cdev->brightness);
init_data.fwnode = of_fwnode_handle(np);

View File

@ -155,7 +155,7 @@ static ssize_t repeat_show(struct device *dev, struct device_attribute *attr,
mutex_unlock(&data->lock);
return scnprintf(buf, PAGE_SIZE, "%d\n", repeat);
return sysfs_emit(buf, "%d\n", repeat);
}
static ssize_t repeat_store(struct device *dev, struct device_attribute *attr,

View File

@ -690,8 +690,7 @@ static int pm860x_charger_probe(struct platform_device *pdev)
(chip->id == CHIP_PM8607) ? chip->companion : chip->client;
if (!info->i2c_8606) {
dev_err(&pdev->dev, "Missed I2C address of 88PM8606!\n");
ret = -EINVAL;
goto out;
return -EINVAL;
}
info->dev = &pdev->dev;
@ -704,44 +703,26 @@ static int pm860x_charger_probe(struct platform_device *pdev)
psy_cfg.drv_data = info;
psy_cfg.supplied_to = pm860x_supplied_to;
psy_cfg.num_supplicants = ARRAY_SIZE(pm860x_supplied_to);
info->usb = power_supply_register(&pdev->dev, &pm860x_charger_desc,
&psy_cfg);
info->usb = devm_power_supply_register(&pdev->dev, &pm860x_charger_desc,
&psy_cfg);
if (IS_ERR(info->usb)) {
ret = PTR_ERR(info->usb);
goto out;
return PTR_ERR(info->usb);
}
pm860x_init_charger(info);
for (i = 0; i < ARRAY_SIZE(info->irq); i++) {
ret = request_threaded_irq(info->irq[i], NULL,
pm860x_irq_descs[i].handler,
IRQF_ONESHOT, pm860x_irq_descs[i].name, info);
ret = devm_request_threaded_irq(&pdev->dev, info->irq[i], NULL,
pm860x_irq_descs[i].handler,
IRQF_ONESHOT,
pm860x_irq_descs[i].name, info);
if (ret < 0) {
dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
info->irq[i], ret);
goto out_irq;
return ret;
}
}
return 0;
out_irq:
power_supply_unregister(info->usb);
while (--i >= 0)
free_irq(info->irq[i], info);
out:
return ret;
}
static int pm860x_charger_remove(struct platform_device *pdev)
{
struct pm860x_charger_info *info = platform_get_drvdata(pdev);
int i;
power_supply_unregister(info->usb);
for (i = 0; i < info->irq_nums; i++)
free_irq(info->irq[i], info);
return 0;
}
static struct platform_driver pm860x_charger_driver = {
@ -749,7 +730,6 @@ static struct platform_driver pm860x_charger_driver = {
.name = "88pm860x-charger",
},
.probe = pm860x_charger_probe,
.remove = pm860x_charger_remove,
};
module_platform_driver(pm860x_charger_driver);

View File

@ -1940,7 +1940,7 @@ static int ab8500_charger_get_ext_psy_data(struct device *dev, void *data)
*
* Due to a asic bug it is necessary to lower the input current to the vbus
* charger when charging with at some specific levels. This issue is only valid
* for below a certain battery voltage. This function makes sure that the
* for below a certain battery voltage. This function makes sure that
* the allowed current limit isn't exceeded.
*/
static void ab8500_charger_check_vbat_work(struct work_struct *work)
@ -3719,7 +3719,14 @@ static int __init ab8500_charger_init(void)
if (ret)
return ret;
return platform_driver_register(&ab8500_charger_driver);
ret = platform_driver_register(&ab8500_charger_driver);
if (ret) {
platform_unregister_drivers(ab8500_charger_component_drivers,
ARRAY_SIZE(ab8500_charger_component_drivers));
return ret;
}
return 0;
}
static void __exit ab8500_charger_exit(void)

View File

@ -694,8 +694,7 @@ static const struct power_supply_desc adp5061_desc = {
.num_properties = ARRAY_SIZE(adp5061_props),
};
static int adp5061_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int adp5061_probe(struct i2c_client *client)
{
struct power_supply_config psy_cfg = {};
struct adp5061_state *st;
@ -737,7 +736,7 @@ static struct i2c_driver adp5061_driver = {
.driver = {
.name = KBUILD_MODNAME,
},
.probe = adp5061_probe,
.probe_new = adp5061_probe,
.id_table = adp5061_id,
};
module_i2c_driver(adp5061_driver);

View File

@ -768,27 +768,13 @@ static const struct power_supply_desc bd9995x_power_supply_desc = {
* Describe the setting in linear_range table.
*/
static const struct linear_range input_current_limit_ranges[] = {
{
.min = 0,
.step = 32000,
.min_sel = 0x0,
.max_sel = 0x1ff,
},
LINEAR_RANGE(0, 0x0, 0x1ff, 32000),
};
/* Possible trickle, pre-charging and termination current values */
static const struct linear_range charging_current_ranges[] = {
{
.min = 0,
.step = 64000,
.min_sel = 0x0,
.max_sel = 0x10,
}, {
.min = 1024000,
.step = 0,
.min_sel = 0x11,
.max_sel = 0x1f,
},
LINEAR_RANGE(0, 0x0, 0x10, 64000),
LINEAR_RANGE(1024000, 0x11, 0x1f, 0),
};
/*
@ -796,72 +782,28 @@ static const struct linear_range charging_current_ranges[] = {
* and battery over voltage protection have same possible values
*/
static const struct linear_range charge_voltage_regulation_ranges[] = {
{
.min = 2560000,
.step = 0,
.min_sel = 0,
.max_sel = 0xA0,
}, {
.min = 2560000,
.step = 16000,
.min_sel = 0xA0,
.max_sel = 0x4B0,
}, {
.min = 19200000,
.step = 0,
.min_sel = 0x4B0,
.max_sel = 0x7FF,
},
LINEAR_RANGE(2560000, 0, 0xA0, 0),
LINEAR_RANGE(2560000, 0xA0, 0x4B0, 16000),
LINEAR_RANGE(19200000, 0x4B0, 0x7FF, 0),
};
/* Possible VSYS voltage regulation values */
static const struct linear_range vsys_voltage_regulation_ranges[] = {
{
.min = 2560000,
.step = 0,
.min_sel = 0,
.max_sel = 0x28,
}, {
.min = 2560000,
.step = 64000,
.min_sel = 0x28,
.max_sel = 0x12C,
}, {
.min = 19200000,
.step = 0,
.min_sel = 0x12C,
.max_sel = 0x1FF,
},
LINEAR_RANGE(2560000, 0, 0x28, 0),
LINEAR_RANGE(2560000, 0x28, 0x12C, 64000),
LINEAR_RANGE(19200000, 0x12C, 0x1FF, 0),
};
/* Possible settings for switching from trickle to pre-charging limits */
static const struct linear_range trickle_to_pre_threshold_ranges[] = {
{
.min = 2048000,
.step = 0,
.min_sel = 0,
.max_sel = 0x20,
}, {
.min = 2048000,
.step = 64000,
.min_sel = 0x20,
.max_sel = 0x12C,
}, {
.min = 19200000,
.step = 0,
.min_sel = 0x12C,
.max_sel = 0x1FF
}
LINEAR_RANGE(2048000, 0, 0x20, 0),
LINEAR_RANGE(2048000, 0x20, 0x12C, 64000),
LINEAR_RANGE(19200000, 0x12C, 0x1FF, 0),
};
/* Possible current values for fast-charging constant current phase */
static const struct linear_range fast_charge_current_ranges[] = {
{
.min = 0,
.step = 64000,
.min_sel = 0,
.max_sel = 0xFF,
}
LINEAR_RANGE(0, 0, 0xFF, 64000),
};
struct battery_init {

View File

@ -1520,9 +1520,9 @@ static int bq2415x_power_supply_init(struct bq2415x_device *bq)
}
/* main bq2415x probe function */
static int bq2415x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int bq2415x_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
int ret;
int num;
char *name = NULL;
@ -1780,7 +1780,7 @@ static struct i2c_driver bq2415x_driver = {
.of_match_table = of_match_ptr(bq2415x_of_match_table),
.acpi_match_table = ACPI_PTR(bq2415x_i2c_acpi_match),
},
.probe = bq2415x_probe,
.probe_new = bq2415x_probe,
.remove = bq2415x_remove,
.id_table = bq2415x_i2c_id_table,
};

View File

@ -1767,9 +1767,9 @@ static int bq24190_get_config(struct bq24190_dev_info *bdi)
return 0;
}
static int bq24190_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int bq24190_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct i2c_adapter *adapter = client->adapter;
struct device *dev = &client->dev;
struct power_supply_config charger_cfg = {}, battery_cfg = {};
@ -2032,7 +2032,7 @@ static const struct of_device_id bq24190_of_match[] = {
MODULE_DEVICE_TABLE(of, bq24190_of_match);
static struct i2c_driver bq24190_driver = {
.probe = bq24190_probe,
.probe_new = bq24190_probe,
.remove = bq24190_remove,
.shutdown = bq24190_shutdown,
.id_table = bq24190_i2c_ids,

View File

@ -947,9 +947,9 @@ static int bq24257_fw_probe(struct bq24257_device *bq)
return 0;
}
static int bq24257_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int bq24257_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct i2c_adapter *adapter = client->adapter;
struct device *dev = &client->dev;
const struct acpi_device_id *acpi_id;
@ -1167,7 +1167,7 @@ static struct i2c_driver bq24257_driver = {
.acpi_match_table = ACPI_PTR(bq24257_acpi_match),
.pm = &bq24257_pm,
},
.probe = bq24257_probe,
.probe_new = bq24257_probe,
.remove = bq24257_remove,
.id_table = bq24257_i2c_ids,
};

View File

@ -352,8 +352,7 @@ static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
return pdata;
}
static int bq24735_charger_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int bq24735_charger_probe(struct i2c_client *client)
{
int ret;
struct bq24735 *charger;
@ -506,7 +505,7 @@ static struct i2c_driver bq24735_charger_driver = {
.name = "bq24735-charger",
.of_match_table = bq24735_match_ids,
},
.probe = bq24735_charger_probe,
.probe_new = bq24735_charger_probe,
.id_table = bq24735_charger_id,
};

View File

@ -1078,9 +1078,9 @@ static const struct regmap_config bq25155_regmap_config = {
.volatile_reg = bq2515x_volatile_register,
};
static int bq2515x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int bq2515x_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device *dev = &client->dev;
struct bq2515x_device *bq2515x;
struct power_supply_config charger_cfg = {};
@ -1158,7 +1158,7 @@ static struct i2c_driver bq2515x_driver = {
.name = "bq2515x-charger",
.of_match_table = bq2515x_of_match,
},
.probe = bq2515x_probe,
.probe_new = bq2515x_probe,
.id_table = bq2515x_i2c_ids,
};
module_i2c_driver(bq2515x_driver);

View File

@ -1619,9 +1619,9 @@ static int bq256xx_parse_dt(struct bq256xx_device *bq,
return 0;
}
static int bq256xx_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int bq256xx_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device *dev = &client->dev;
struct bq256xx_device *bq;
struct power_supply_config psy_cfg = { };
@ -1744,7 +1744,7 @@ static struct i2c_driver bq256xx_driver = {
.of_match_table = bq256xx_of_match,
.acpi_match_table = bq256xx_acpi_match,
},
.probe = bq256xx_probe,
.probe_new = bq256xx_probe,
.id_table = bq256xx_i2c_ids,
};
module_i2c_driver(bq256xx_driver);

View File

@ -529,40 +529,6 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
val->intval = bq25890_find_val(bq->init_data.ichg, TBL_ICHG);
/* When temperature is too low, charge current is decreased */
if (bq->state.ntc_fault == NTC_FAULT_COOL) {
ret = bq25890_field_read(bq, F_JEITA_ISET);
if (ret < 0)
return ret;
if (ret)
val->intval /= 5;
else
val->intval /= 2;
}
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
if (!state.online) {
val->intval = 0;
break;
}
ret = bq25890_field_read(bq, F_BATV); /* read measured value */
if (ret < 0)
return ret;
/* converted_val = 2.304V + ADC_val * 20mV (table 10.3.15) */
val->intval = 2304000 + ret * 20000;
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
val->intval = bq25890_find_val(bq->init_data.vreg, TBL_VREG);
break;
case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
val->intval = bq25890_find_val(bq->init_data.iprechg, TBL_ITERM);
break;
@ -579,8 +545,71 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
val->intval = bq25890_find_val(ret, TBL_IINLIM);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = bq25890_field_read(bq, F_SYSV); /* read measured value */
case POWER_SUPPLY_PROP_CURRENT_NOW: /* I_BAT now */
/*
* This is ADC-sampled immediate charge current supplied
* from charger to battery. The property name is confusing,
* for clarification refer to:
* Documentation/ABI/testing/sysfs-class-power
* /sys/class/power_supply/<supply_name>/current_now
*/
ret = bq25890_field_read(bq, F_ICHGR); /* read measured value */
if (ret < 0)
return ret;
/* converted_val = ADC_val * 50mA (table 10.3.19) */
val->intval = ret * -50000;
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: /* I_BAT user limit */
/*
* This is user-configured constant charge current supplied
* from charger to battery in first phase of charging, when
* battery voltage is below constant charge voltage.
*
* This value reflects the current hardware setting.
*
* The POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX is the
* maximum value of this property.
*/
ret = bq25890_field_read(bq, F_ICHG);
if (ret < 0)
return ret;
val->intval = bq25890_find_val(ret, TBL_ICHG);
/* When temperature is too low, charge current is decreased */
if (bq->state.ntc_fault == NTC_FAULT_COOL) {
ret = bq25890_field_read(bq, F_JEITA_ISET);
if (ret < 0)
return ret;
if (ret)
val->intval /= 5;
else
val->intval /= 2;
}
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: /* I_BAT max */
/*
* This is maximum allowed constant charge current supplied
* from charger to battery in first phase of charging, when
* battery voltage is below constant charge voltage.
*
* This value is constant for each battery and set from DT.
*/
val->intval = bq25890_find_val(bq->init_data.ichg, TBL_ICHG);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW: /* V_BAT now */
/*
* This is ADC-sampled immediate charge voltage supplied
* from charger to battery. The property name is confusing,
* for clarification refer to:
* Documentation/ABI/testing/sysfs-class-power
* /sys/class/power_supply/<supply_name>/voltage_now
*/
ret = bq25890_field_read(bq, F_BATV); /* read measured value */
if (ret < 0)
return ret;
@ -588,13 +617,33 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
val->intval = 2304000 + ret * 20000;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
ret = bq25890_field_read(bq, F_ICHGR); /* read measured value */
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: /* V_BAT user limit */
/*
* This is user-configured constant charge voltage supplied
* from charger to battery in second phase of charging, when
* battery voltage reached constant charge voltage.
*
* This value reflects the current hardware setting.
*
* The POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX is the
* maximum value of this property.
*/
ret = bq25890_field_read(bq, F_VREG);
if (ret < 0)
return ret;
/* converted_val = ADC_val * 50mA (table 10.3.19) */
val->intval = ret * -50000;
val->intval = bq25890_find_val(ret, TBL_VREG);
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: /* V_BAT max */
/*
* This is maximum allowed constant charge voltage supplied
* from charger to battery in second phase of charging, when
* battery voltage reached constant charge voltage.
*
* This value is constant for each battery and set from DT.
*/
val->intval = bq25890_find_val(bq->init_data.vreg, TBL_VREG);
break;
case POWER_SUPPLY_PROP_TEMP:
@ -618,9 +667,18 @@ static int bq25890_power_supply_set_property(struct power_supply *psy,
const union power_supply_propval *val)
{
struct bq25890_device *bq = power_supply_get_drvdata(psy);
int maxval;
u8 lval;
switch (psp) {
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
maxval = bq25890_find_val(bq->init_data.ichg, TBL_ICHG);
lval = bq25890_find_idx(min(val->intval, maxval), TBL_ICHG);
return bq25890_field_write(bq, F_ICHG, lval);
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
maxval = bq25890_find_val(bq->init_data.vreg, TBL_VREG);
lval = bq25890_find_idx(min(val->intval, maxval), TBL_VREG);
return bq25890_field_write(bq, F_VREG, lval);
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
lval = bq25890_find_idx(val->intval, TBL_IINLIM);
return bq25890_field_write(bq, F_IINLIM, lval);
@ -633,6 +691,8 @@ static int bq25890_power_supply_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
switch (psp) {
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
return true;
default:
@ -880,6 +940,7 @@ static const enum power_supply_property bq25890_power_supply_props[] = {
POWER_SUPPLY_PROP_CHARGE_TYPE,
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
@ -1034,10 +1095,32 @@ static int bq25890_vbus_is_enabled(struct regulator_dev *rdev)
return bq25890_field_read(bq, F_OTG_CFG);
}
static int bq25890_vbus_get_voltage(struct regulator_dev *rdev)
{
struct bq25890_device *bq = rdev_get_drvdata(rdev);
return bq25890_get_vbus_voltage(bq);
}
static int bq25890_vsys_get_voltage(struct regulator_dev *rdev)
{
struct bq25890_device *bq = rdev_get_drvdata(rdev);
int ret;
/* Should be some output voltage ? */
ret = bq25890_field_read(bq, F_SYSV); /* read measured value */
if (ret < 0)
return ret;
/* converted_val = 2.304V + ADC_val * 20mV (table 10.3.15) */
return 2304000 + ret * 20000;
}
static const struct regulator_ops bq25890_vbus_ops = {
.enable = bq25890_vbus_enable,
.disable = bq25890_vbus_disable,
.is_enabled = bq25890_vbus_is_enabled,
.get_voltage = bq25890_vbus_get_voltage,
};
static const struct regulator_desc bq25890_vbus_desc = {
@ -1046,9 +1129,54 @@ static const struct regulator_desc bq25890_vbus_desc = {
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.ops = &bq25890_vbus_ops,
.fixed_uV = 5000000,
.n_voltages = 1,
};
static const struct regulator_ops bq25890_vsys_ops = {
.get_voltage = bq25890_vsys_get_voltage,
};
static const struct regulator_desc bq25890_vsys_desc = {
.name = "vsys",
.of_match = "vsys",
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.ops = &bq25890_vsys_ops,
};
static int bq25890_register_regulator(struct bq25890_device *bq)
{
struct bq25890_platform_data *pdata = dev_get_platdata(bq->dev);
struct regulator_config cfg = {
.dev = bq->dev,
.driver_data = bq,
};
struct regulator_dev *reg;
if (pdata)
cfg.init_data = pdata->regulator_init_data;
reg = devm_regulator_register(bq->dev, &bq25890_vbus_desc, &cfg);
if (IS_ERR(reg)) {
return dev_err_probe(bq->dev, PTR_ERR(reg),
"registering vbus regulator");
}
/* pdata->regulator_init_data is for vbus only */
cfg.init_data = NULL;
reg = devm_regulator_register(bq->dev, &bq25890_vsys_desc, &cfg);
if (IS_ERR(reg)) {
return dev_err_probe(bq->dev, PTR_ERR(reg),
"registering vsys regulator");
}
return 0;
}
#else
static inline int
bq25890_register_regulator(struct bq25890_device *bq)
{
return 0;
}
#endif
static int bq25890_get_chip_version(struct bq25890_device *bq)
@ -1189,8 +1317,14 @@ static int bq25890_fw_probe(struct bq25890_device *bq)
return 0;
}
static int bq25890_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static void bq25890_non_devm_cleanup(void *data)
{
struct bq25890_device *bq = data;
cancel_delayed_work_sync(&bq->pump_express_work);
}
static int bq25890_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct bq25890_device *bq;
@ -1244,56 +1378,47 @@ static int bq25890_probe(struct i2c_client *client,
/* OTG reporting */
bq->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
if (!IS_ERR_OR_NULL(bq->usb_phy)) {
INIT_WORK(&bq->usb_work, bq25890_usb_work);
bq->usb_nb.notifier_call = bq25890_usb_notifier;
usb_register_notifier(bq->usb_phy, &bq->usb_nb);
}
#ifdef CONFIG_REGULATOR
else {
struct bq25890_platform_data *pdata = dev_get_platdata(dev);
struct regulator_config cfg = { };
struct regulator_dev *reg;
cfg.dev = dev;
cfg.driver_data = bq;
if (pdata)
cfg.init_data = pdata->regulator_init_data;
/*
* This must be before bq25890_power_supply_init(), so that it runs
* after devm unregisters the power_supply.
*/
ret = devm_add_action_or_reset(dev, bq25890_non_devm_cleanup, bq);
if (ret)
return ret;
reg = devm_regulator_register(dev, &bq25890_vbus_desc, &cfg);
if (IS_ERR(reg))
return dev_err_probe(dev, PTR_ERR(reg), "registering regulator");
}
#endif
ret = bq25890_register_regulator(bq);
if (ret)
return ret;
ret = bq25890_power_supply_init(bq);
if (ret < 0) {
dev_err(dev, "Failed to register power supply\n");
goto err_unregister_usb_notifier;
}
if (ret < 0)
return dev_err_probe(dev, ret, "registering power supply\n");
ret = devm_request_threaded_irq(dev, client->irq, NULL,
bq25890_irq_handler_thread,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
BQ25890_IRQ_PIN, bq);
if (ret)
goto err_unregister_usb_notifier;
return ret;
if (!IS_ERR_OR_NULL(bq->usb_phy)) {
INIT_WORK(&bq->usb_work, bq25890_usb_work);
bq->usb_nb.notifier_call = bq25890_usb_notifier;
usb_register_notifier(bq->usb_phy, &bq->usb_nb);
}
return 0;
err_unregister_usb_notifier:
if (!IS_ERR_OR_NULL(bq->usb_phy))
usb_unregister_notifier(bq->usb_phy, &bq->usb_nb);
return ret;
}
static void bq25890_remove(struct i2c_client *client)
{
struct bq25890_device *bq = i2c_get_clientdata(client);
if (!IS_ERR_OR_NULL(bq->usb_phy))
if (!IS_ERR_OR_NULL(bq->usb_phy)) {
usb_unregister_notifier(bq->usb_phy, &bq->usb_nb);
cancel_work_sync(&bq->usb_work);
}
if (!bq->skip_reset) {
/* reset all registers to default values */
@ -1400,7 +1525,7 @@ static struct i2c_driver bq25890_driver = {
.acpi_match_table = ACPI_PTR(bq25890_acpi_match),
.pm = &bq25890_pm,
},
.probe = bq25890_probe,
.probe_new = bq25890_probe,
.remove = bq25890_remove,
.shutdown = bq25890_shutdown,
.id_table = bq25890_i2c_ids,

View File

@ -1207,9 +1207,9 @@ static int bq25980_parse_dt(struct bq25980_device *bq)
return 0;
}
static int bq25980_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int bq25980_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device *dev = &client->dev;
struct bq25980_device *bq;
int ret;
@ -1287,7 +1287,7 @@ static struct i2c_driver bq25980_driver = {
.name = "bq25980-charger",
.of_match_table = bq25980_of_match,
},
.probe = bq25980_probe,
.probe_new = bq25980_probe,
.id_table = bq25980_i2c_ids,
};
module_i2c_driver(bq25980_driver);

View File

@ -136,9 +136,9 @@ static int bq27xxx_battery_i2c_bulk_write(struct bq27xxx_device_info *di,
return 0;
}
static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int bq27xxx_battery_i2c_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct bq27xxx_device_info *di;
int ret;
char *name;
@ -295,7 +295,7 @@ static struct i2c_driver bq27xxx_battery_i2c_driver = {
.name = "bq27xxx-battery",
.of_match_table = of_match_ptr(bq27xxx_battery_i2c_of_match_table),
},
.probe = bq27xxx_battery_i2c_probe,
.probe_new = bq27xxx_battery_i2c_probe,
.remove = bq27xxx_battery_i2c_remove,
.id_table = bq27xxx_i2c_id_table,
};

View File

@ -699,6 +699,9 @@ static int cw_bat_probe(struct i2c_client *client)
}
cw_bat->battery_workqueue = create_singlethread_workqueue("rk_battery");
if (!cw_bat->battery_workqueue)
return -ENOMEM;
devm_delayed_work_autocancel(&client->dev,
&cw_bat->battery_delay_work, cw_bat_work);
queue_delayed_work(cw_bat->battery_workqueue,

View File

@ -368,9 +368,9 @@ static const struct ds278x_battery_ops ds278x_ops[] = {
}
};
static int ds278x_battery_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int ds278x_battery_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct ds278x_platform_data *pdata = client->dev.platform_data;
struct power_supply_config psy_cfg = {};
struct ds278x_info *info;
@ -458,7 +458,7 @@ static struct i2c_driver ds278x_battery_driver = {
.name = "ds2782-battery",
.pm = &ds278x_battery_pm_ops,
},
.probe = ds278x_battery_probe,
.probe_new = ds278x_battery_probe,
.remove = ds278x_battery_remove,
.id_table = ds278x_id,
};

View File

@ -540,7 +540,7 @@ static struct lp8727_platform_data *lp8727_parse_dt(struct device *dev)
}
#endif
static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
static int lp8727_probe(struct i2c_client *cl)
{
struct lp8727_chg *pchg;
struct lp8727_platform_data *pdata;
@ -615,7 +615,7 @@ static struct i2c_driver lp8727_driver = {
.name = "lp8727",
.of_match_table = of_match_ptr(lp8727_dt_ids),
},
.probe = lp8727_probe,
.probe_new = lp8727_probe,
.remove = lp8727_remove,
.id_table = lp8727_ids,
};

View File

@ -520,7 +520,7 @@ err_free_irq:
static int lp8788_irq_register(struct platform_device *pdev,
struct lp8788_charger *pchg)
{
const char *name[] = {
static const char * const name[] = {
LP8788_CHG_IRQ, LP8788_PRSW_IRQ, LP8788_BATT_IRQ
};
int i;

View File

@ -439,8 +439,7 @@ static enum power_supply_property ltc294x_properties[] = {
POWER_SUPPLY_PROP_CURRENT_NOW,
};
static int ltc294x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int ltc294x_i2c_probe(struct i2c_client *client)
{
struct power_supply_config psy_cfg = {};
struct ltc294x_info *info;
@ -636,7 +635,7 @@ static struct i2c_driver ltc294x_driver = {
.of_match_table = ltc294x_i2c_of_match,
.pm = LTC294X_PM_OPS,
},
.probe = ltc294x_i2c_probe,
.probe_new = ltc294x_i2c_probe,
.shutdown = ltc294x_i2c_shutdown,
.id_table = ltc294x_i2c_id,
};

View File

@ -819,8 +819,7 @@ static void ltc4162l_clear_interrupts(struct ltc4162l_info *info)
regmap_write(info->regmap, LTC4162L_CHARGE_STATUS_ALERTS_REG, 0);
}
static int ltc4162l_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int ltc4162l_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
struct device *dev = &client->dev;
@ -916,7 +915,7 @@ static const struct of_device_id ltc4162l_of_match[] = {
MODULE_DEVICE_TABLE(of, ltc4162l_of_match);
static struct i2c_driver ltc4162l_driver = {
.probe = ltc4162l_probe,
.probe_new = ltc4162l_probe,
.alert = ltc4162l_alert,
.id_table = ltc4162l_i2c_id_table,
.driver = {

View File

@ -234,8 +234,7 @@ static enum power_supply_property max14656_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};
static int max14656_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int max14656_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
struct device *dev = &client->dev;
@ -317,7 +316,7 @@ static struct i2c_driver max14656_i2c_driver = {
.name = "max14656",
.of_match_table = max14656_match_table,
},
.probe = max14656_probe,
.probe_new = max14656_probe,
.id_table = max14656_id,
};
module_i2c_driver(max14656_i2c_driver);

View File

@ -430,9 +430,9 @@ static const struct power_supply_desc max17040_battery_desc = {
.num_properties = ARRAY_SIZE(max17040_battery_props),
};
static int max17040_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int max17040_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct i2c_adapter *adapter = client->adapter;
struct power_supply_config psy_cfg = {};
struct max17040_chip *chip;
@ -599,7 +599,7 @@ static struct i2c_driver max17040_i2c_driver = {
.of_match_table = max17040_of_match,
.pm = MAX17040_PM_OPS,
},
.probe = max17040_probe,
.probe_new = max17040_probe,
.id_table = max17040_id,
};
module_i2c_driver(max17040_i2c_driver);

View File

@ -1031,9 +1031,9 @@ static const struct power_supply_desc max17042_no_current_sense_psy_desc = {
.num_properties = ARRAY_SIZE(max17042_battery_props) - 2,
};
static int max17042_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int max17042_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct i2c_adapter *adapter = client->adapter;
const struct power_supply_desc *max17042_desc = &max17042_psy_desc;
struct power_supply_config psy_cfg = {};
@ -1220,7 +1220,7 @@ static struct i2c_driver max17042_i2c_driver = {
.of_match_table = of_match_ptr(max17042_dt_match),
.pm = &max17042_pm_ops,
},
.probe = max17042_probe,
.probe_new = max17042_probe,
.id_table = max17042_id,
};
module_i2c_driver(max17042_i2c_driver);

View File

@ -113,16 +113,13 @@ enum {
MT6360_RANGE_MAX,
};
#define MT6360_LINEAR_RANGE(idx, _min, _min_sel, _max_sel, _step) \
[idx] = REGULATOR_LINEAR_RANGE(_min, _min_sel, _max_sel, _step)
static const struct linear_range mt6360_chg_range[MT6360_RANGE_MAX] = {
MT6360_LINEAR_RANGE(MT6360_RANGE_VMIVR, 3900000, 0, 0x5F, 100000),
MT6360_LINEAR_RANGE(MT6360_RANGE_ICHG, 100000, 0, 0x31, 100000),
MT6360_LINEAR_RANGE(MT6360_RANGE_VOREG, 3900000, 0, 0x51, 10000),
MT6360_LINEAR_RANGE(MT6360_RANGE_AICR, 100000, 0, 0x3F, 50000),
MT6360_LINEAR_RANGE(MT6360_RANGE_IPREC, 100000, 0, 0x0F, 50000),
MT6360_LINEAR_RANGE(MT6360_RANGE_IEOC, 100000, 0, 0x0F, 50000),
LINEAR_RANGE_IDX(MT6360_RANGE_VMIVR, 3900000, 0, 0x5F, 100000),
LINEAR_RANGE_IDX(MT6360_RANGE_ICHG, 100000, 0, 0x31, 100000),
LINEAR_RANGE_IDX(MT6360_RANGE_VOREG, 3900000, 0, 0x51, 10000),
LINEAR_RANGE_IDX(MT6360_RANGE_AICR, 100000, 0, 0x3F, 50000),
LINEAR_RANGE_IDX(MT6360_RANGE_IPREC, 100000, 0, 0x0F, 50000),
LINEAR_RANGE_IDX(MT6360_RANGE_IEOC, 100000, 0, 0x0F, 50000),
};
struct mt6360_chg_info {

View File

@ -750,6 +750,11 @@ int power_supply_get_battery_info(struct power_supply *psy,
int i, tab_len, size;
propname = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index);
if (!propname) {
power_supply_put_battery_info(psy, info);
err = -ENOMEM;
goto out_put_node;
}
list = of_get_property(battery_np, propname, &size);
if (!list || !size) {
dev_err(&psy->dev, "failed to get %s\n", propname);
@ -870,7 +875,6 @@ EXPORT_SYMBOL_GPL(power_supply_temp2resist_simple);
* power_supply_vbat2ri() - find the battery internal resistance
* from the battery voltage
* @info: The battery information container
* @table: Pointer to battery resistance temperature table
* @vbat_uv: The battery voltage in microvolt
* @charging: If we are charging (true) or not (false)
*
@ -1387,8 +1391,8 @@ create_triggers_failed:
register_cooler_failed:
psy_unregister_thermal(psy);
register_thermal_failed:
device_del(dev);
wakeup_init_failed:
device_del(dev);
device_add_failed:
check_supplies_failed:
dev_set_name_failed:

View File

@ -1060,8 +1060,10 @@ static int rk817_charger_probe(struct platform_device *pdev)
return -ENODEV;
charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
if (!charger)
if (!charger) {
of_node_put(node);
return -ENOMEM;
}
charger->rk808 = rk808;

View File

@ -112,8 +112,7 @@ static const struct power_supply_desc rt5033_battery_desc = {
.num_properties = ARRAY_SIZE(rt5033_battery_props),
};
static int rt5033_battery_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int rt5033_battery_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
struct power_supply_config psy_cfg = {};
@ -173,7 +172,7 @@ static struct i2c_driver rt5033_battery_driver = {
.name = "rt5033-battery",
.of_match_table = rt5033_battery_of_match,
},
.probe = rt5033_battery_probe,
.probe_new = rt5033_battery_probe,
.remove = rt5033_battery_remove,
.id_table = rt5033_battery_id,
};

View File

@ -1581,8 +1581,7 @@ static const struct regmap_config rt9455_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
static int rt9455_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int rt9455_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
struct device *dev = &client->dev;
@ -1738,7 +1737,7 @@ MODULE_DEVICE_TABLE(acpi, rt9455_i2c_acpi_match);
#endif
static struct i2c_driver rt9455_driver = {
.probe = rt9455_probe,
.probe_new = rt9455_probe,
.remove = rt9455_remove,
.id_table = rt9455_i2c_id_table,
.driver = {

View File

@ -162,8 +162,7 @@ static const struct power_supply_desc sbs_desc = {
.get_property = sbs_get_property,
};
static int sbs_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int sbs_probe(struct i2c_client *client)
{
struct power_supply_config psy_cfg = {};
struct sbs_info *chip;
@ -241,7 +240,7 @@ static const struct i2c_device_id sbs_id[] = {
MODULE_DEVICE_TABLE(i2c, sbs_id);
static struct i2c_driver sbs_driver = {
.probe = sbs_probe,
.probe_new = sbs_probe,
.id_table = sbs_id,
.driver = {
.name = "sbs-charger",

View File

@ -315,9 +315,9 @@ static void sbsm_del_mux_adapter(void *data)
i2c_mux_del_adapters(sbsm->muxc);
}
static int sbsm_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int sbsm_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct i2c_adapter *adapter = client->adapter;
struct sbsm_data *data;
struct device *dev = &client->dev;
@ -409,7 +409,7 @@ static struct i2c_driver sbsm_driver = {
.name = "sbsm",
.of_match_table = of_match_ptr(sbsm_dt_ids),
},
.probe = sbsm_probe,
.probe_new = sbsm_probe,
.alert = sbsm_alert,
.id_table = sbsm_ids
};

View File

@ -1528,9 +1528,9 @@ static const struct regulator_desc smb347_usb_vbus_regulator_desc = {
.n_voltages = 1,
};
static int smb347_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int smb347_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct power_supply_config mains_usb_cfg = {};
struct regulator_config usb_rdev_cfg = {};
struct device *dev = &client->dev;
@ -1629,7 +1629,7 @@ static struct i2c_driver smb347_driver = {
.name = "smb347",
.of_match_table = smb3xx_of_match,
},
.probe = smb347_probe,
.probe_new = smb347_probe,
.remove = smb347_remove,
.shutdown = smb347_shutdown,
.id_table = smb347_id,

View File

@ -532,8 +532,7 @@ static const struct regulator_desc ucs1002_regulator_descriptor = {
.n_voltages = 1,
};
static int ucs1002_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
static int ucs1002_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct power_supply_config charger_config = {};
@ -681,7 +680,7 @@ static struct i2c_driver ucs1002_driver = {
.name = "ucs1002",
.of_match_table = ucs1002_of_match,
},
.probe = ucs1002_probe,
.probe_new = ucs1002_probe,
};
module_i2c_driver(ucs1002_driver);

View File

@ -176,8 +176,7 @@ static int z2_batt_ps_init(struct z2_charger *charger, int props)
return 0;
}
static int z2_batt_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int z2_batt_probe(struct i2c_client *client)
{
int ret = 0;
int props = 1; /* POWER_SUPPLY_PROP_PRESENT */
@ -206,10 +205,12 @@ static int z2_batt_probe(struct i2c_client *client,
charger->charge_gpiod = devm_gpiod_get_optional(&client->dev,
NULL, GPIOD_IN);
if (IS_ERR(charger->charge_gpiod))
return dev_err_probe(&client->dev,
if (IS_ERR(charger->charge_gpiod)) {
ret = dev_err_probe(&client->dev,
PTR_ERR(charger->charge_gpiod),
"failed to get charge GPIO\n");
goto err;
}
if (charger->charge_gpiod) {
gpiod_set_consumer_name(charger->charge_gpiod, "BATT CHRG");
@ -306,7 +307,7 @@ static struct i2c_driver z2_batt_driver = {
.name = "z2-battery",
.pm = Z2_BATTERY_PM_OPS
},
.probe = z2_batt_probe,
.probe_new = z2_batt_probe,
.remove = z2_batt_remove,
.id_table = z2_batt_id,
};

View File

@ -1055,6 +1055,13 @@ config ADVANTECH_WDT
feature. More information can be found at
<https://www.advantech.com.tw/products/>
config ADVANTECH_EC_WDT
tristate "Advantech Embedded Controller Watchdog Timer"
depends on X86
help
This driver supports Advantech products with ITE based Embedded Controller.
It does not support Advantech products with other ECs or without EC.
config ALIM1535_WDT
tristate "ALi M1535 PMU Watchdog Timer"
depends on X86 && PCI

View File

@ -102,6 +102,7 @@ obj-$(CONFIG_SUNPLUS_WATCHDOG) += sunplus_wdt.o
# X86 (i386 + ia64 + x86_64) Architecture
obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
obj-$(CONFIG_ADVANTECH_EC_WDT) += advantech_ec_wdt.o
obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
obj-$(CONFIG_EBC_C384_WDT) += ebc-c384_wdt.o

View File

@ -0,0 +1,205 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Advantech Embedded Controller Watchdog Driver
*
* This driver supports Advantech products with ITE based Embedded Controller.
* It does not support Advantech products with other ECs or without EC.
*
* Copyright (C) 2022 Advantech Europe B.V.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/isa.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/watchdog.h>
#define DRIVER_NAME "advantech_ec_wdt"
/* EC IO region */
#define EC_BASE_ADDR 0x299
#define EC_ADDR_EXTENT 2
/* EC minimum IO access delay in ms */
#define EC_MIN_DELAY 10
/* EC interface definitions */
#define EC_ADDR_CMD (EC_BASE_ADDR + 1)
#define EC_ADDR_DATA EC_BASE_ADDR
#define EC_CMD_EC_PROBE 0x30
#define EC_CMD_COMM 0x89
#define EC_CMD_WDT_START 0x28
#define EC_CMD_WDT_STOP 0x29
#define EC_CMD_WDT_RESET 0x2A
#define EC_DAT_EN_DLY_H 0x58
#define EC_DAT_EN_DLY_L 0x59
#define EC_DAT_RST_DLY_H 0x5E
#define EC_DAT_RST_DLY_L 0x5F
#define EC_MAGIC 0x95
/* module parameters */
#define MIN_TIME 1
#define MAX_TIME 6000 /* 100 minutes */
#define DEFAULT_TIME 60
static unsigned int timeout;
static ktime_t ec_timestamp;
module_param(timeout, uint, 0);
MODULE_PARM_DESC(timeout,
"Default Watchdog timer setting (" __MODULE_STRING(DEFAULT_TIME) "s). The range is from " __MODULE_STRING(MIN_TIME) " to " __MODULE_STRING(MAX_TIME) ".");
static void adv_ec_wdt_timing_gate(void)
{
ktime_t time_cur, time_delta;
/* ensure minimum delay between IO accesses*/
time_cur = ktime_get();
time_delta = ktime_to_ms(ktime_sub(time_cur, ec_timestamp));
if (time_delta < EC_MIN_DELAY) {
time_delta = EC_MIN_DELAY - time_delta;
usleep_range(time_delta * 1000, (time_delta + 1) * 1000);
}
ec_timestamp = ktime_get();
}
static void adv_ec_wdt_outb(unsigned char value, unsigned short port)
{
adv_ec_wdt_timing_gate();
outb(value, port);
}
static unsigned char adv_ec_wdt_inb(unsigned short port)
{
adv_ec_wdt_timing_gate();
return inb(port);
}
static int adv_ec_wdt_ping(struct watchdog_device *wdd)
{
adv_ec_wdt_outb(EC_CMD_WDT_RESET, EC_ADDR_CMD);
return 0;
}
static int adv_ec_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
{
unsigned int val;
/* scale time to EC 100 ms base */
val = t * 10;
/* reset enable delay, just in case it was set by BIOS etc. */
adv_ec_wdt_outb(EC_CMD_COMM, EC_ADDR_CMD);
adv_ec_wdt_outb(EC_DAT_EN_DLY_H, EC_ADDR_DATA);
adv_ec_wdt_outb(0, EC_ADDR_DATA);
adv_ec_wdt_outb(EC_CMD_COMM, EC_ADDR_CMD);
adv_ec_wdt_outb(EC_DAT_EN_DLY_L, EC_ADDR_DATA);
adv_ec_wdt_outb(0, EC_ADDR_DATA);
/* set reset delay */
adv_ec_wdt_outb(EC_CMD_COMM, EC_ADDR_CMD);
adv_ec_wdt_outb(EC_DAT_RST_DLY_H, EC_ADDR_DATA);
adv_ec_wdt_outb(val >> 8, EC_ADDR_DATA);
adv_ec_wdt_outb(EC_CMD_COMM, EC_ADDR_CMD);
adv_ec_wdt_outb(EC_DAT_RST_DLY_L, EC_ADDR_DATA);
adv_ec_wdt_outb(val & 0xFF, EC_ADDR_DATA);
wdd->timeout = t;
return 0;
}
static int adv_ec_wdt_start(struct watchdog_device *wdd)
{
adv_ec_wdt_set_timeout(wdd, wdd->timeout);
adv_ec_wdt_outb(EC_CMD_WDT_START, EC_ADDR_CMD);
return 0;
}
static int adv_ec_wdt_stop(struct watchdog_device *wdd)
{
adv_ec_wdt_outb(EC_CMD_WDT_STOP, EC_ADDR_CMD);
return 0;
}
static const struct watchdog_info adv_ec_wdt_info = {
.identity = DRIVER_NAME,
.options = WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE |
WDIOF_KEEPALIVEPING,
};
static const struct watchdog_ops adv_ec_wdt_ops = {
.owner = THIS_MODULE,
.start = adv_ec_wdt_start,
.stop = adv_ec_wdt_stop,
.ping = adv_ec_wdt_ping,
.set_timeout = adv_ec_wdt_set_timeout,
};
static struct watchdog_device adv_ec_wdt_dev = {
.info = &adv_ec_wdt_info,
.ops = &adv_ec_wdt_ops,
.min_timeout = MIN_TIME,
.max_timeout = MAX_TIME,
.timeout = DEFAULT_TIME,
};
static int adv_ec_wdt_probe(struct device *dev, unsigned int id)
{
if (!devm_request_region(dev, EC_BASE_ADDR, EC_ADDR_EXTENT, dev_name(dev))) {
dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
EC_BASE_ADDR, EC_BASE_ADDR + EC_ADDR_EXTENT);
return -EBUSY;
}
watchdog_init_timeout(&adv_ec_wdt_dev, timeout, dev);
watchdog_stop_on_reboot(&adv_ec_wdt_dev);
watchdog_stop_on_unregister(&adv_ec_wdt_dev);
return devm_watchdog_register_device(dev, &adv_ec_wdt_dev);
}
static struct isa_driver adv_ec_wdt_driver = {
.probe = adv_ec_wdt_probe,
.driver = {
.name = DRIVER_NAME,
},
};
static int __init adv_ec_wdt_init(void)
{
unsigned int val;
/* quick probe for EC */
if (!request_region(EC_BASE_ADDR, EC_ADDR_EXTENT, DRIVER_NAME))
return -EBUSY;
adv_ec_wdt_outb(EC_CMD_EC_PROBE, EC_ADDR_CMD);
val = adv_ec_wdt_inb(EC_ADDR_DATA);
release_region(EC_BASE_ADDR, EC_ADDR_EXTENT);
if (val != EC_MAGIC)
return -ENODEV;
return isa_register_driver(&adv_ec_wdt_driver, 1);
}
static void __exit adv_ec_wdt_exit(void)
{
isa_unregister_driver(&adv_ec_wdt_driver);
}
module_init(adv_ec_wdt_init);
module_exit(adv_ec_wdt_exit);
MODULE_AUTHOR("Thomas Kastner <thomas.kastner@advantech.com>");
MODULE_DESCRIPTION("Advantech Embedded Controller Watchdog Device Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("20221019");
MODULE_ALIAS("isa:" DRIVER_NAME);

View File

@ -5,11 +5,14 @@
* Joel Stanley <joel@jms.id.au>
*/
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/watchdog.h>
@ -18,28 +21,41 @@ module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
struct aspeed_wdt_config {
u32 ext_pulse_width_mask;
u32 irq_shift;
u32 irq_mask;
};
struct aspeed_wdt {
struct watchdog_device wdd;
void __iomem *base;
u32 ctrl;
};
struct aspeed_wdt_config {
u32 ext_pulse_width_mask;
const struct aspeed_wdt_config *cfg;
};
static const struct aspeed_wdt_config ast2400_config = {
.ext_pulse_width_mask = 0xff,
.irq_shift = 0,
.irq_mask = 0,
};
static const struct aspeed_wdt_config ast2500_config = {
.ext_pulse_width_mask = 0xfffff,
.irq_shift = 12,
.irq_mask = GENMASK(31, 12),
};
static const struct aspeed_wdt_config ast2600_config = {
.ext_pulse_width_mask = 0xfffff,
.irq_shift = 0,
.irq_mask = GENMASK(31, 10),
};
static const struct of_device_id aspeed_wdt_of_table[] = {
{ .compatible = "aspeed,ast2400-wdt", .data = &ast2400_config },
{ .compatible = "aspeed,ast2500-wdt", .data = &ast2500_config },
{ .compatible = "aspeed,ast2600-wdt", .data = &ast2500_config },
{ .compatible = "aspeed,ast2600-wdt", .data = &ast2600_config },
{ },
};
MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
@ -58,6 +74,7 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
#define WDT_CTRL_RESET_SYSTEM BIT(1)
#define WDT_CTRL_ENABLE BIT(0)
#define WDT_TIMEOUT_STATUS 0x10
#define WDT_TIMEOUT_STATUS_IRQ BIT(2)
#define WDT_TIMEOUT_STATUS_BOOT_SECONDARY BIT(1)
#define WDT_CLEAR_TIMEOUT_STATUS 0x14
#define WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION BIT(0)
@ -160,6 +177,26 @@ static int aspeed_wdt_set_timeout(struct watchdog_device *wdd,
return 0;
}
static int aspeed_wdt_set_pretimeout(struct watchdog_device *wdd,
unsigned int pretimeout)
{
struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
u32 actual = pretimeout * WDT_RATE_1MHZ;
u32 s = wdt->cfg->irq_shift;
u32 m = wdt->cfg->irq_mask;
wdd->pretimeout = pretimeout;
wdt->ctrl &= ~m;
if (pretimeout)
wdt->ctrl |= ((actual << s) & m) | WDT_CTRL_WDT_INTR;
else
wdt->ctrl &= ~WDT_CTRL_WDT_INTR;
writel(wdt->ctrl, wdt->base + WDT_CTRL);
return 0;
}
static int aspeed_wdt_restart(struct watchdog_device *wdd,
unsigned long action, void *data)
{
@ -232,6 +269,7 @@ static const struct watchdog_ops aspeed_wdt_ops = {
.stop = aspeed_wdt_stop,
.ping = aspeed_wdt_ping,
.set_timeout = aspeed_wdt_set_timeout,
.set_pretimeout = aspeed_wdt_set_pretimeout,
.restart = aspeed_wdt_restart,
.owner = THIS_MODULE,
};
@ -243,10 +281,29 @@ static const struct watchdog_info aspeed_wdt_info = {
.identity = KBUILD_MODNAME,
};
static const struct watchdog_info aspeed_wdt_pretimeout_info = {
.options = WDIOF_KEEPALIVEPING
| WDIOF_PRETIMEOUT
| WDIOF_MAGICCLOSE
| WDIOF_SETTIMEOUT,
.identity = KBUILD_MODNAME,
};
static irqreturn_t aspeed_wdt_irq(int irq, void *arg)
{
struct watchdog_device *wdd = arg;
struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
u32 status = readl(wdt->base + WDT_TIMEOUT_STATUS);
if (status & WDT_TIMEOUT_STATUS_IRQ)
watchdog_notify_pretimeout(wdd);
return IRQ_HANDLED;
}
static int aspeed_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct aspeed_wdt_config *config;
const struct of_device_id *ofdid;
struct aspeed_wdt *wdt;
struct device_node *np;
@ -259,11 +316,33 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (!wdt)
return -ENOMEM;
np = dev->of_node;
ofdid = of_match_node(aspeed_wdt_of_table, np);
if (!ofdid)
return -EINVAL;
wdt->cfg = ofdid->data;
wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
wdt->wdd.info = &aspeed_wdt_info;
if (wdt->cfg->irq_mask) {
int irq = platform_get_irq_optional(pdev, 0);
if (irq > 0) {
ret = devm_request_irq(dev, irq, aspeed_wdt_irq,
IRQF_SHARED, dev_name(dev),
wdt);
if (ret)
return ret;
wdt->wdd.info = &aspeed_wdt_pretimeout_info;
}
}
wdt->wdd.ops = &aspeed_wdt_ops;
wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS;
wdt->wdd.parent = dev;
@ -273,13 +352,6 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(&wdt->wdd, nowayout);
np = dev->of_node;
ofdid = of_match_node(aspeed_wdt_of_table, np);
if (!ofdid)
return -EINVAL;
config = ofdid->data;
/*
* On clock rates:
* - ast2400 wdt can run at PCLK, or 1MHz
@ -331,7 +403,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
(of_device_is_compatible(np, "aspeed,ast2600-wdt"))) {
u32 reg = readl(wdt->base + WDT_RESET_WIDTH);
reg &= config->ext_pulse_width_mask;
reg &= wdt->cfg->ext_pulse_width_mask;
if (of_property_read_bool(np, "aspeed,ext-active-high"))
reg |= WDT_ACTIVE_HIGH_MAGIC;
else
@ -339,7 +411,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
writel(reg, wdt->base + WDT_RESET_WIDTH);
reg &= config->ext_pulse_width_mask;
reg &= wdt->cfg->ext_pulse_width_mask;
if (of_property_read_bool(np, "aspeed,ext-push-pull"))
reg |= WDT_PUSH_PULL_MAGIC;
else
@ -349,7 +421,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
}
if (!of_property_read_u32(np, "aspeed,ext-pulse-duration", &duration)) {
u32 max_duration = config->ext_pulse_width_mask + 1;
u32 max_duration = wdt->cfg->ext_pulse_width_mask + 1;
if (duration == 0 || duration > max_duration) {
dev_err(dev, "Invalid pulse duration: %uus\n",

View File

@ -278,8 +278,6 @@ static void at91wdt_shutdown(struct platform_device *pdev)
at91_wdt_stop();
}
#ifdef CONFIG_PM
static int at91wdt_suspend(struct platform_device *pdev, pm_message_t message)
{
at91_wdt_stop();
@ -293,11 +291,6 @@ static int at91wdt_resume(struct platform_device *pdev)
return 0;
}
#else
#define at91wdt_suspend NULL
#define at91wdt_resume NULL
#endif
static const struct of_device_id at91_wdt_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-wdt" },
{ /* sentinel */ }
@ -308,8 +301,8 @@ static struct platform_driver at91wdt_driver = {
.probe = at91wdt_probe,
.remove = at91wdt_remove,
.shutdown = at91wdt_shutdown,
.suspend = at91wdt_suspend,
.resume = at91wdt_resume,
.suspend = pm_ptr(at91wdt_suspend),
.resume = pm_ptr(at91wdt_resume),
.driver = {
.name = "atmel_st_watchdog",
.of_match_table = at91_wdt_dt_ids,

View File

@ -105,7 +105,6 @@ static int db8500_wdt_probe(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM
static int db8500_wdt_suspend(struct platform_device *pdev,
pm_message_t state)
{
@ -130,15 +129,11 @@ static int db8500_wdt_resume(struct platform_device *pdev)
}
return 0;
}
#else
#define db8500_wdt_suspend NULL
#define db8500_wdt_resume NULL
#endif
static struct platform_driver db8500_wdt_driver = {
.probe = db8500_wdt_probe,
.suspend = db8500_wdt_suspend,
.resume = db8500_wdt_resume,
.suspend = pm_ptr(db8500_wdt_suspend),
.resume = pm_ptr(db8500_wdt_resume),
.driver = {
.name = "db8500_wdt",
},

View File

@ -423,14 +423,18 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
return time_left;
}
static void iTCO_wdt_set_running(struct iTCO_wdt_private *p)
/* Returns true if the watchdog was running */
static bool iTCO_wdt_set_running(struct iTCO_wdt_private *p)
{
u16 val;
/* Bit 11: TCO Timer Halt -> 0 = The TCO timer is * enabled */
/* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled */
val = inw(TCO1_CNT(p));
if (!(val & BIT(11)))
if (!(val & BIT(11))) {
set_bit(WDOG_HW_RUNNING, &p->wddev.status);
return true;
}
return false;
}
/*
@ -518,9 +522,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
return -ENODEV; /* Cannot reset NO_REBOOT bit */
}
/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
p->update_no_reboot_bit(p->no_reboot_priv, true);
if (turn_SMI_watchdog_clear_off >= p->iTCO_version) {
/*
* Bit 13: TCO_EN -> 0
@ -572,7 +573,13 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(&p->wddev, p);
platform_set_drvdata(pdev, p);
iTCO_wdt_set_running(p);
if (!iTCO_wdt_set_running(p)) {
/*
* If the watchdog was not running set NO_REBOOT now to
* prevent later reboots.
*/
p->update_no_reboot_bit(p->no_reboot_priv, true);
}
/* Check that the heartbeat value is within it's range;
if not reset to the default */

View File

@ -75,9 +75,7 @@ struct kempld_wdt_data {
struct watchdog_device wdd;
unsigned int pretimeout;
struct kempld_wdt_stage stage[KEMPLD_WDT_MAX_STAGES];
#ifdef CONFIG_PM
u8 pm_status_store;
#endif
};
#define DEFAULT_TIMEOUT 30 /* seconds */
@ -495,7 +493,6 @@ static int kempld_wdt_probe(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM
/* Disable watchdog if it is active during suspend */
static int kempld_wdt_suspend(struct platform_device *pdev,
pm_message_t message)
@ -531,18 +528,14 @@ static int kempld_wdt_resume(struct platform_device *pdev)
else
return kempld_wdt_stop(wdd);
}
#else
#define kempld_wdt_suspend NULL
#define kempld_wdt_resume NULL
#endif
static struct platform_driver kempld_wdt_driver = {
.driver = {
.name = "kempld-wdt",
},
.probe = kempld_wdt_probe,
.suspend = kempld_wdt_suspend,
.resume = kempld_wdt_resume,
.suspend = pm_ptr(kempld_wdt_suspend),
.resume = pm_ptr(kempld_wdt_resume),
};
module_platform_driver(kempld_wdt_driver);

View File

@ -10,9 +10,11 @@
*/
#include <dt-bindings/reset/mt2712-resets.h>
#include <dt-bindings/reset/mediatek,mt6795-resets.h>
#include <dt-bindings/reset/mt7986-resets.h>
#include <dt-bindings/reset/mt8183-resets.h>
#include <dt-bindings/reset/mt8186-resets.h>
#include <dt-bindings/reset/mt8188-resets.h>
#include <dt-bindings/reset/mt8192-resets.h>
#include <dt-bindings/reset/mt8195-resets.h>
#include <linux/delay.h>
@ -78,6 +80,10 @@ static const struct mtk_wdt_data mt2712_data = {
.toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
};
static const struct mtk_wdt_data mt6795_data = {
.toprgu_sw_rst_num = MT6795_TOPRGU_SW_RST_NUM,
};
static const struct mtk_wdt_data mt7986_data = {
.toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM,
};
@ -90,6 +96,10 @@ static const struct mtk_wdt_data mt8186_data = {
.toprgu_sw_rst_num = MT8186_TOPRGU_SW_RST_NUM,
};
static const struct mtk_wdt_data mt8188_data = {
.toprgu_sw_rst_num = MT8188_TOPRGU_SW_RST_NUM,
};
static const struct mtk_wdt_data mt8192_data = {
.toprgu_sw_rst_num = MT8192_TOPRGU_SW_RST_NUM,
};
@ -426,9 +436,11 @@ static int mtk_wdt_resume(struct device *dev)
static const struct of_device_id mtk_wdt_dt_ids[] = {
{ .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
{ .compatible = "mediatek,mt6589-wdt" },
{ .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data },
{ .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
{ .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
{ .compatible = "mediatek,mt8186-wdt", .data = &mt8186_data },
{ .compatible = "mediatek,mt8188-wdt", .data = &mt8188_data },
{ .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
{ .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data },
{ /* sentinel */ }

View File

@ -316,8 +316,6 @@ static int omap_wdt_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM
/* REVISIT ... not clear this is the best way to handle system suspend; and
* it's very inappropriate for selective device suspend (e.g. suspending this
* through sysfs rather than by stopping the watchdog daemon). Also, this
@ -353,11 +351,6 @@ static int omap_wdt_resume(struct platform_device *pdev)
return 0;
}
#else
#define omap_wdt_suspend NULL
#define omap_wdt_resume NULL
#endif
static const struct of_device_id omap_wdt_of_match[] = {
{ .compatible = "ti,omap3-wdt", },
{},
@ -368,8 +361,8 @@ static struct platform_driver omap_wdt_driver = {
.probe = omap_wdt_probe,
.remove = omap_wdt_remove,
.shutdown = omap_wdt_shutdown,
.suspend = omap_wdt_suspend,
.resume = omap_wdt_resume,
.suspend = pm_ptr(omap_wdt_suspend),
.resume = pm_ptr(omap_wdt_resume),
.driver = {
.name = "omap_wdt",
.of_match_table = omap_wdt_of_match,

View File

@ -144,6 +144,8 @@ static int rn5t618_wdt_probe(struct platform_device *pdev)
struct rn5t618 *rn5t618 = dev_get_drvdata(dev->parent);
struct rn5t618_wdt *wdt;
int min_timeout, max_timeout;
int ret;
unsigned int val;
wdt = devm_kzalloc(dev, sizeof(struct rn5t618_wdt), GFP_KERNEL);
if (!wdt)
@ -160,6 +162,16 @@ static int rn5t618_wdt_probe(struct platform_device *pdev)
wdt->wdt_dev.timeout = max_timeout;
wdt->wdt_dev.parent = dev;
/* Read out previous power-off factor */
ret = regmap_read(wdt->rn5t618->regmap, RN5T618_POFFHIS, &val);
if (ret)
return ret;
if (val & RN5T618_POFFHIS_VINDET)
wdt->wdt_dev.bootstatus = WDIOF_POWERUNDER;
else if (val & RN5T618_POFFHIS_WDG)
wdt->wdt_dev.bootstatus = WDIOF_CARDRESET;
watchdog_set_drvdata(&wdt->wdt_dev, wdt);
watchdog_init_timeout(&wdt->wdt_dev, timeout, dev);
watchdog_set_nowayout(&wdt->wdt_dev, nowayout);

View File

@ -81,7 +81,6 @@ static int twl4030_wdt_probe(struct platform_device *pdev)
return devm_watchdog_register_device(dev, wdt);
}
#ifdef CONFIG_PM
static int twl4030_wdt_suspend(struct platform_device *pdev, pm_message_t state)
{
struct watchdog_device *wdt = platform_get_drvdata(pdev);
@ -99,10 +98,6 @@ static int twl4030_wdt_resume(struct platform_device *pdev)
return 0;
}
#else
#define twl4030_wdt_suspend NULL
#define twl4030_wdt_resume NULL
#endif
static const struct of_device_id twl_wdt_of_match[] = {
{ .compatible = "ti,twl4030-wdt", },
@ -112,8 +107,8 @@ MODULE_DEVICE_TABLE(of, twl_wdt_of_match);
static struct platform_driver twl4030_wdt_driver = {
.probe = twl4030_wdt_probe,
.suspend = twl4030_wdt_suspend,
.resume = twl4030_wdt_resume,
.suspend = pm_ptr(twl4030_wdt_suspend),
.resume = pm_ptr(twl4030_wdt_resume),
.driver = {
.name = "twl4030_wdt",
.of_match_table = twl_wdt_of_match,

View File

@ -427,8 +427,6 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
return error;
kaddr = kmap_atomic(page);
if (dsize > gfs2_max_stuffed_size(ip))
dsize = gfs2_max_stuffed_size(ip);
memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
kunmap_atomic(kaddr);

View File

@ -61,9 +61,6 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
void *kaddr = kmap(page);
u64 dsize = i_size_read(inode);
if (dsize > gfs2_max_stuffed_size(ip))
dsize = gfs2_max_stuffed_size(ip);
memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
kunmap(page);

View File

@ -1445,14 +1445,13 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
static void __flock_holder_uninit(struct file *file, struct gfs2_holder *fl_gh)
{
struct gfs2_glock *gl = fl_gh->gh_gl;
struct gfs2_glock *gl = gfs2_glock_hold(fl_gh->gh_gl);
/*
* Make sure gfs2_glock_put() won't sleep under the file->f_lock
* spinlock.
*/
gfs2_glock_hold(gl);
spin_lock(&file->f_lock);
gfs2_holder_uninit(fl_gh);
spin_unlock(&file->f_lock);

View File

@ -186,10 +186,11 @@ void gfs2_glock_free(struct gfs2_glock *gl)
*
*/
void gfs2_glock_hold(struct gfs2_glock *gl)
struct gfs2_glock *gfs2_glock_hold(struct gfs2_glock *gl)
{
GLOCK_BUG_ON(gl, __lockref_is_dead(&gl->gl_lockref));
lockref_get(&gl->gl_lockref);
return gl;
}
/**
@ -205,12 +206,6 @@ static int demote_ok(const struct gfs2_glock *gl)
if (gl->gl_state == LM_ST_UNLOCKED)
return 0;
/*
* Note that demote_ok is used for the lru process of disposing of
* glocks. For this purpose, we don't care if the glock's holders
* have the HIF_MAY_DEMOTE flag set or not. If someone is using
* them, don't demote.
*/
if (!list_empty(&gl->gl_holders))
return 0;
if (glops->go_demote_ok)
@ -393,7 +388,7 @@ static void do_error(struct gfs2_glock *gl, const int ret)
struct gfs2_holder *gh, *tmp;
list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
if (!test_bit(HIF_WAIT, &gh->gh_iflags))
if (test_bit(HIF_HOLDER, &gh->gh_iflags))
continue;
if (ret & LM_OUT_ERROR)
gh->gh_error = -EIO;
@ -407,45 +402,6 @@ static void do_error(struct gfs2_glock *gl, const int ret)
}
}
/**
* demote_incompat_holders - demote incompatible demoteable holders
* @gl: the glock we want to promote
* @current_gh: the newly promoted holder
*
* We're passing the newly promoted holder in @current_gh, but actually, any of
* the strong holders would do.
*/
static void demote_incompat_holders(struct gfs2_glock *gl,
struct gfs2_holder *current_gh)
{
struct gfs2_holder *gh, *tmp;
/*
* Demote incompatible holders before we make ourselves eligible.
* (This holder may or may not allow auto-demoting, but we don't want
* to demote the new holder before it's even granted.)
*/
list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
/*
* Since holders are at the front of the list, we stop when we
* find the first non-holder.
*/
if (!test_bit(HIF_HOLDER, &gh->gh_iflags))
return;
if (gh == current_gh)
continue;
if (test_bit(HIF_MAY_DEMOTE, &gh->gh_iflags) &&
!may_grant(gl, current_gh, gh)) {
/*
* We should not recurse into do_promote because
* __gfs2_glock_dq only calls handle_callback,
* gfs2_glock_add_to_lru and __gfs2_glock_queue_work.
*/
__gfs2_glock_dq(gh);
}
}
}
/**
* find_first_holder - find the first "holder" gh
* @gl: the glock
@ -464,26 +420,6 @@ static inline struct gfs2_holder *find_first_holder(const struct gfs2_glock *gl)
return NULL;
}
/**
* find_first_strong_holder - find the first non-demoteable holder
* @gl: the glock
*
* Find the first holder that doesn't have the HIF_MAY_DEMOTE flag set.
*/
static inline struct gfs2_holder *
find_first_strong_holder(struct gfs2_glock *gl)
{
struct gfs2_holder *gh;
list_for_each_entry(gh, &gl->gl_holders, gh_list) {
if (!test_bit(HIF_HOLDER, &gh->gh_iflags))
return NULL;
if (!test_bit(HIF_MAY_DEMOTE, &gh->gh_iflags))
return gh;
}
return NULL;
}
/*
* gfs2_instantiate - Call the glops instantiate function
* @gh: The glock holder
@ -540,9 +476,8 @@ done:
static int do_promote(struct gfs2_glock *gl)
{
struct gfs2_holder *gh, *current_gh;
bool incompat_holders_demoted = false;
current_gh = find_first_strong_holder(gl);
current_gh = find_first_holder(gl);
list_for_each_entry(gh, &gl->gl_holders, gh_list) {
if (test_bit(HIF_HOLDER, &gh->gh_iflags))
continue;
@ -561,11 +496,8 @@ static int do_promote(struct gfs2_glock *gl)
set_bit(HIF_HOLDER, &gh->gh_iflags);
trace_gfs2_promote(gh);
gfs2_holder_wake(gh);
if (!incompat_holders_demoted) {
if (!current_gh)
current_gh = gh;
demote_incompat_holders(gl, current_gh);
incompat_holders_demoted = true;
}
}
return 0;
}
@ -927,6 +859,48 @@ out_unlock:
return;
}
/**
* glock_set_object - set the gl_object field of a glock
* @gl: the glock
* @object: the object
*/
void glock_set_object(struct gfs2_glock *gl, void *object)
{
void *prev_object;
spin_lock(&gl->gl_lockref.lock);
prev_object = gl->gl_object;
gl->gl_object = object;
spin_unlock(&gl->gl_lockref.lock);
if (gfs2_assert_warn(gl->gl_name.ln_sbd, prev_object == NULL)) {
pr_warn("glock=%u/%llx\n",
gl->gl_name.ln_type,
(unsigned long long)gl->gl_name.ln_number);
gfs2_dump_glock(NULL, gl, true);
}
}
/**
* glock_clear_object - clear the gl_object field of a glock
* @gl: the glock
*/
void glock_clear_object(struct gfs2_glock *gl, void *object)
{
void *prev_object;
spin_lock(&gl->gl_lockref.lock);
prev_object = gl->gl_object;
gl->gl_object = NULL;
spin_unlock(&gl->gl_lockref.lock);
if (gfs2_assert_warn(gl->gl_name.ln_sbd,
prev_object == object || prev_object == NULL)) {
pr_warn("glock=%u/%llx\n",
gl->gl_name.ln_type,
(unsigned long long)gl->gl_name.ln_number);
gfs2_dump_glock(NULL, gl, true);
}
}
void gfs2_inode_remember_delete(struct gfs2_glock *gl, u64 generation)
{
struct gfs2_inode_lvb *ri = (void *)gl->gl_lksb.sb_lvbptr;
@ -980,8 +954,6 @@ static bool gfs2_try_evict(struct gfs2_glock *gl)
ip = NULL;
spin_unlock(&gl->gl_lockref.lock);
if (ip) {
struct gfs2_glock *inode_gl = NULL;
gl->gl_no_formal_ino = ip->i_no_formal_ino;
set_bit(GIF_DEFERRED_DELETE, &ip->i_flags);
d_prune_aliases(&ip->i_inode);
@ -991,14 +963,14 @@ static bool gfs2_try_evict(struct gfs2_glock *gl)
spin_lock(&gl->gl_lockref.lock);
ip = gl->gl_object;
if (ip) {
inode_gl = ip->i_gl;
lockref_get(&inode_gl->gl_lockref);
clear_bit(GIF_DEFERRED_DELETE, &ip->i_flags);
if (!igrab(&ip->i_inode))
ip = NULL;
}
spin_unlock(&gl->gl_lockref.lock);
if (inode_gl) {
gfs2_glock_poke(inode_gl);
gfs2_glock_put(inode_gl);
if (ip) {
gfs2_glock_poke(ip->i_gl);
iput(&ip->i_inode);
}
evicted = !ip;
}
@ -1039,6 +1011,7 @@ static void delete_work_func(struct work_struct *work)
if (gfs2_queue_delete_work(gl, 5 * HZ))
return;
}
goto out;
}
inode = gfs2_lookup_by_inum(sdp, no_addr, gl->gl_no_formal_ino,
@ -1051,6 +1024,7 @@ static void delete_work_func(struct work_struct *work)
d_prune_aliases(inode);
iput(inode);
}
out:
gfs2_glock_put(gl);
}
@ -1256,13 +1230,12 @@ void __gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, u16 flags,
struct gfs2_holder *gh, unsigned long ip)
{
INIT_LIST_HEAD(&gh->gh_list);
gh->gh_gl = gl;
gh->gh_gl = gfs2_glock_hold(gl);
gh->gh_ip = ip;
gh->gh_owner_pid = get_pid(task_pid(current));
gh->gh_state = state;
gh->gh_flags = flags;
gh->gh_iflags = 0;
gfs2_glock_hold(gl);
}
/**
@ -1496,7 +1469,7 @@ __acquires(&gl->gl_lockref.lock)
if (test_bit(GLF_LOCK, &gl->gl_flags)) {
struct gfs2_holder *current_gh;
current_gh = find_first_strong_holder(gl);
current_gh = find_first_holder(gl);
try_futile = !may_grant(gl, current_gh, gh);
}
if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags))
@ -1508,8 +1481,6 @@ __acquires(&gl->gl_lockref.lock)
continue;
if (gh->gh_gl->gl_ops->go_type == LM_TYPE_FLOCK)
continue;
if (test_bit(HIF_MAY_DEMOTE, &gh2->gh_iflags))
continue;
if (!pid_is_meaningful(gh2))
continue;
goto trap_recursive;
@ -1619,69 +1590,28 @@ static inline bool needs_demote(struct gfs2_glock *gl)
static void __gfs2_glock_dq(struct gfs2_holder *gh)
{
struct gfs2_glock *gl = gh->gh_gl;
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
unsigned delay = 0;
int fast_path = 0;
/*
* This while loop is similar to function demote_incompat_holders:
* If the glock is due to be demoted (which may be from another node
* or even if this holder is GL_NOCACHE), the weak holders are
* demoted as well, allowing the glock to be demoted.
* This holder should not be cached, so mark it for demote.
* Note: this should be done before the check for needs_demote
* below.
*/
while (gh) {
/*
* If we're in the process of file system withdraw, we cannot
* just dequeue any glocks until our journal is recovered, lest
* we introduce file system corruption. We need two exceptions
* to this rule: We need to allow unlocking of nondisk glocks
* and the glock for our own journal that needs recovery.
*/
if (test_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags) &&
glock_blocked_by_withdraw(gl) &&
gh->gh_gl != sdp->sd_jinode_gl) {
sdp->sd_glock_dqs_held++;
spin_unlock(&gl->gl_lockref.lock);
might_sleep();
wait_on_bit(&sdp->sd_flags, SDF_WITHDRAW_RECOVERY,
TASK_UNINTERRUPTIBLE);
spin_lock(&gl->gl_lockref.lock);
}
if (gh->gh_flags & GL_NOCACHE)
handle_callback(gl, LM_ST_UNLOCKED, 0, false);
/*
* This holder should not be cached, so mark it for demote.
* Note: this should be done before the check for needs_demote
* below.
*/
if (gh->gh_flags & GL_NOCACHE)
handle_callback(gl, LM_ST_UNLOCKED, 0, false);
list_del_init(&gh->gh_list);
clear_bit(HIF_HOLDER, &gh->gh_iflags);
trace_gfs2_glock_queue(gh, 0);
list_del_init(&gh->gh_list);
clear_bit(HIF_HOLDER, &gh->gh_iflags);
trace_gfs2_glock_queue(gh, 0);
/*
* If there hasn't been a demote request we are done.
* (Let the remaining holders, if any, keep holding it.)
*/
if (!needs_demote(gl)) {
if (list_empty(&gl->gl_holders))
fast_path = 1;
break;
}
/*
* If we have another strong holder (we cannot auto-demote)
* we are done. It keeps holding it until it is done.
*/
if (find_first_strong_holder(gl))
break;
/*
* If we have a weak holder at the head of the list, it
* (and all others like it) must be auto-demoted. If there
* are no more weak holders, we exit the while loop.
*/
gh = find_first_holder(gl);
/*
* If there hasn't been a demote request we are done.
* (Let the remaining holders, if any, keep holding it.)
*/
if (!needs_demote(gl)) {
if (list_empty(&gl->gl_holders))
fast_path = 1;
}
if (!test_bit(GLF_LFLUSH, &gl->gl_flags) && demote_ok(gl))
@ -1705,8 +1635,17 @@ static void __gfs2_glock_dq(struct gfs2_holder *gh)
void gfs2_glock_dq(struct gfs2_holder *gh)
{
struct gfs2_glock *gl = gh->gh_gl;
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
spin_lock(&gl->gl_lockref.lock);
if (!gfs2_holder_queued(gh)) {
/*
* May have already been dequeued because the locking request
* was GL_ASYNC and it has failed in the meantime.
*/
goto out;
}
if (list_is_first(&gh->gh_list, &gl->gl_holders) &&
!test_bit(HIF_HOLDER, &gh->gh_iflags)) {
spin_unlock(&gl->gl_lockref.lock);
@ -1715,7 +1654,26 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
spin_lock(&gl->gl_lockref.lock);
}
/*
* If we're in the process of file system withdraw, we cannot just
* dequeue any glocks until our journal is recovered, lest we introduce
* file system corruption. We need two exceptions to this rule: We need
* to allow unlocking of nondisk glocks and the glock for our own
* journal that needs recovery.
*/
if (test_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags) &&
glock_blocked_by_withdraw(gl) &&
gh->gh_gl != sdp->sd_jinode_gl) {
sdp->sd_glock_dqs_held++;
spin_unlock(&gl->gl_lockref.lock);
might_sleep();
wait_on_bit(&sdp->sd_flags, SDF_WITHDRAW_RECOVERY,
TASK_UNINTERRUPTIBLE);
spin_lock(&gl->gl_lockref.lock);
}
__gfs2_glock_dq(gh);
out:
spin_unlock(&gl->gl_lockref.lock);
}
@ -1888,33 +1846,6 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state)
if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags))
delay = gl->gl_hold_time;
}
/*
* Note 1: We cannot call demote_incompat_holders from handle_callback
* or gfs2_set_demote due to recursion problems like: gfs2_glock_dq ->
* handle_callback -> demote_incompat_holders -> gfs2_glock_dq
* Plus, we only want to demote the holders if the request comes from
* a remote cluster node because local holder conflicts are resolved
* elsewhere.
*
* Note 2: if a remote node wants this glock in EX mode, lock_dlm will
* request that we set our state to UNLOCKED. Here we mock up a holder
* to make it look like someone wants the lock EX locally. Any SH
* and DF requests should be able to share the lock without demoting.
*
* Note 3: We only want to demote the demoteable holders when there
* are no more strong holders. The demoteable holders might as well
* keep the glock until the last strong holder is done with it.
*/
if (!find_first_strong_holder(gl)) {
struct gfs2_holder mock_gh = {
.gh_gl = gl,
.gh_state = (state == LM_ST_UNLOCKED) ?
LM_ST_EXCLUSIVE : state,
.gh_iflags = BIT(HIF_HOLDER)
};
demote_incompat_holders(gl, &mock_gh);
}
handle_callback(gl, state, delay, true);
__gfs2_glock_queue_work(gl, delay);
spin_unlock(&gl->gl_lockref.lock);
@ -2306,8 +2237,6 @@ static const char *hflags2str(char *buf, u16 flags, unsigned long iflags)
*p++ = 'H';
if (test_bit(HIF_WAIT, &iflags))
*p++ = 'W';
if (test_bit(HIF_MAY_DEMOTE, &iflags))
*p++ = 'D';
if (flags & GL_SKIP)
*p++ = 's';
*p = 0;

View File

@ -156,8 +156,6 @@ static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *
list_for_each_entry(gh, &gl->gl_holders, gh_list) {
if (!test_bit(HIF_HOLDER, &gh->gh_iflags))
break;
if (test_bit(HIF_MAY_DEMOTE, &gh->gh_iflags))
continue;
if (gh->gh_owner_pid == pid)
goto out;
}
@ -196,7 +194,7 @@ static inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl)
extern int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
const struct gfs2_glock_operations *glops,
int create, struct gfs2_glock **glp);
extern void gfs2_glock_hold(struct gfs2_glock *gl);
extern struct gfs2_glock *gfs2_glock_hold(struct gfs2_glock *gl);
extern void gfs2_glock_put(struct gfs2_glock *gl);
extern void gfs2_glock_queue_put(struct gfs2_glock *gl);
@ -288,6 +286,9 @@ extern void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp);
extern void gfs2_register_debugfs(void);
extern void gfs2_unregister_debugfs(void);
extern void glock_set_object(struct gfs2_glock *gl, void *object);
extern void glock_clear_object(struct gfs2_glock *gl, void *object);
extern const struct lm_lockops gfs2_dlm_ops;
static inline void gfs2_holder_mark_uninitialized(struct gfs2_holder *gh)
@ -305,64 +306,6 @@ static inline bool gfs2_holder_queued(struct gfs2_holder *gh)
return !list_empty(&gh->gh_list);
}
/**
* glock_set_object - set the gl_object field of a glock
* @gl: the glock
* @object: the object
*/
static inline void glock_set_object(struct gfs2_glock *gl, void *object)
{
spin_lock(&gl->gl_lockref.lock);
if (gfs2_assert_warn(gl->gl_name.ln_sbd, gl->gl_object == NULL))
gfs2_dump_glock(NULL, gl, true);
gl->gl_object = object;
spin_unlock(&gl->gl_lockref.lock);
}
/**
* glock_clear_object - clear the gl_object field of a glock
* @gl: the glock
* @object: the object
*
* I'd love to similarly add this:
* else if (gfs2_assert_warn(gl->gl_sbd, gl->gl_object == object))
* gfs2_dump_glock(NULL, gl, true);
* Unfortunately, that's not possible because as soon as gfs2_delete_inode
* frees the block in the rgrp, another process can reassign it for an I_NEW
* inode in gfs2_create_inode because that calls new_inode, not gfs2_iget.
* That means gfs2_delete_inode may subsequently try to call this function
* for a glock that's already pointing to a brand new inode. If we clear the
* new inode's gl_object, we'll introduce metadata corruption. Function
* gfs2_delete_inode calls clear_inode which calls gfs2_clear_inode which also
* tries to clear gl_object, so it's more than just gfs2_delete_inode.
*
*/
static inline void glock_clear_object(struct gfs2_glock *gl, void *object)
{
spin_lock(&gl->gl_lockref.lock);
if (gl->gl_object == object)
gl->gl_object = NULL;
spin_unlock(&gl->gl_lockref.lock);
}
static inline void gfs2_holder_allow_demote(struct gfs2_holder *gh)
{
struct gfs2_glock *gl = gh->gh_gl;
spin_lock(&gl->gl_lockref.lock);
set_bit(HIF_MAY_DEMOTE, &gh->gh_iflags);
spin_unlock(&gl->gl_lockref.lock);
}
static inline void gfs2_holder_disallow_demote(struct gfs2_holder *gh)
{
struct gfs2_glock *gl = gh->gh_gl;
spin_lock(&gl->gl_lockref.lock);
clear_bit(HIF_MAY_DEMOTE, &gh->gh_iflags);
spin_unlock(&gl->gl_lockref.lock);
}
extern void gfs2_inode_remember_delete(struct gfs2_glock *gl, u64 generation);
extern bool gfs2_inode_already_deleted(struct gfs2_glock *gl, u64 generation);

View File

@ -397,38 +397,39 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
struct timespec64 atime;
u16 height, depth;
umode_t mode = be32_to_cpu(str->di_mode);
bool is_new = ip->i_inode.i_state & I_NEW;
struct inode *inode = &ip->i_inode;
bool is_new = inode->i_state & I_NEW;
if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
goto corrupt;
if (unlikely(!is_new && inode_wrong_type(&ip->i_inode, mode)))
if (unlikely(!is_new && inode_wrong_type(inode, mode)))
goto corrupt;
ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
ip->i_inode.i_mode = mode;
inode->i_mode = mode;
if (is_new) {
ip->i_inode.i_rdev = 0;
inode->i_rdev = 0;
switch (mode & S_IFMT) {
case S_IFBLK:
case S_IFCHR:
ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major),
be32_to_cpu(str->di_minor));
inode->i_rdev = MKDEV(be32_to_cpu(str->di_major),
be32_to_cpu(str->di_minor));
break;
}
}
i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid));
i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid));
set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink));
i_size_write(&ip->i_inode, be64_to_cpu(str->di_size));
gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
i_uid_write(inode, be32_to_cpu(str->di_uid));
i_gid_write(inode, be32_to_cpu(str->di_gid));
set_nlink(inode, be32_to_cpu(str->di_nlink));
i_size_write(inode, be64_to_cpu(str->di_size));
gfs2_set_inode_blocks(inode, be64_to_cpu(str->di_blocks));
atime.tv_sec = be64_to_cpu(str->di_atime);
atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
if (timespec64_compare(&ip->i_inode.i_atime, &atime) < 0)
ip->i_inode.i_atime = atime;
ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
if (timespec64_compare(&inode->i_atime, &atime) < 0)
inode->i_atime = atime;
inode->i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
inode->i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
inode->i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
inode->i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
ip->i_goal = be64_to_cpu(str->di_goal_meta);
ip->i_generation = be64_to_cpu(str->di_generation);
@ -436,7 +437,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
ip->i_diskflags = be32_to_cpu(str->di_flags);
ip->i_eattr = be64_to_cpu(str->di_eattr);
/* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
gfs2_set_inode_flags(&ip->i_inode);
gfs2_set_inode_flags(inode);
height = be16_to_cpu(str->di_height);
if (unlikely(height > GFS2_MAX_META_HEIGHT))
goto corrupt;
@ -448,8 +449,11 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
ip->i_depth = (u8)depth;
ip->i_entries = be32_to_cpu(str->di_entries);
if (S_ISREG(ip->i_inode.i_mode))
gfs2_set_aops(&ip->i_inode);
if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip))
goto corrupt;
if (S_ISREG(inode->i_mode))
gfs2_set_aops(inode);
return 0;
corrupt:

View File

@ -252,7 +252,6 @@ struct gfs2_lkstats {
enum {
/* States */
HIF_MAY_DEMOTE = 1,
HIF_HOLDER = 6, /* Set for gh that "holds" the glock */
HIF_WAIT = 10,
};

View File

@ -142,6 +142,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
if (unlikely(error))
goto fail;
/*
* The only caller that sets @blktype to GFS2_BLKST_UNLINKED is
* delete_work_func(). Make sure not to cancel the delete work
* from within itself here.
*/
if (blktype == GFS2_BLKST_UNLINKED)
extra_flags |= LM_FLAG_TRY;
else
@ -403,12 +408,17 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags, unsigned *dblocks)
goto out_ipreserv;
error = gfs2_alloc_blocks(ip, &ip->i_no_addr, dblocks, 1, &ip->i_generation);
if (error)
goto out_trans_end;
ip->i_no_formal_ino = ip->i_generation;
ip->i_inode.i_ino = ip->i_no_addr;
ip->i_goal = ip->i_no_addr;
if (*dblocks > 1)
ip->i_eattr = ip->i_no_addr + 1;
out_trans_end:
gfs2_trans_end(sdp);
out_ipreserv:
gfs2_inplace_release(ip);
out_quota:
@ -586,6 +596,12 @@ static int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
* @size: The initial size of the inode (ignored for directories)
* @excl: Force fail if inode exists
*
* FIXME: Change to allocate the disk blocks and write them out in the same
* transaction. That way, we can no longer end up in a situation in which an
* inode is allocated, the node crashes, and the block looks like a valid
* inode. (With atomic creates in place, we will also no longer need to zero
* the link count and dirty the inode here on failure.)
*
* Returns: 0 on success, or error code
*/
@ -596,12 +612,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
{
const struct qstr *name = &dentry->d_name;
struct posix_acl *default_acl, *acl;
struct gfs2_holder ghs[2];
struct gfs2_holder d_gh, gh;
struct inode *inode = NULL;
struct gfs2_inode *dip = GFS2_I(dir), *ip;
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct gfs2_glock *io_gl;
int error, free_vfs_inode = 1;
int error;
u32 aflags = 0;
unsigned blocks = 1;
struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
@ -617,10 +633,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
if (error)
goto fail;
error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &d_gh);
if (error)
goto fail;
gfs2_holder_mark_uninitialized(ghs + 1);
gfs2_holder_mark_uninitialized(&gh);
error = create_ok(dip, name, mode);
if (error)
@ -642,7 +658,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
else
error = finish_no_open(file, NULL);
}
gfs2_glock_dq_uninit(ghs);
gfs2_glock_dq_uninit(&d_gh);
goto fail;
} else if (error != -ENOENT) {
goto fail_gunlock;
@ -656,12 +672,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
error = -ENOMEM;
if (!inode)
goto fail_gunlock;
ip = GFS2_I(inode);
error = posix_acl_create(dir, &mode, &default_acl, &acl);
if (error)
goto fail_gunlock;
ip = GFS2_I(inode);
error = gfs2_qa_get(ip);
if (error)
goto fail_free_acls;
@ -723,15 +739,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
goto fail_free_inode;
gfs2_cancel_delete_work(io_gl);
retry:
error = insert_inode_locked4(inode, ip->i_no_addr, iget_test, &ip->i_no_addr);
BUG_ON(error);
if (error == -EBUSY)
goto retry;
if (error)
goto fail_gunlock2;
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT | GL_NOPID,
&ip->i_iopen_gh);
if (error)
goto fail_gunlock2;
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh);
if (error)
goto fail_gunlock3;
@ -739,10 +759,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
if (error)
goto fail_gunlock3;
if (blocks > 1) {
ip->i_eattr = ip->i_no_addr + 1;
if (blocks > 1)
gfs2_init_xattr(ip);
}
init_dinode(dip, ip, symname);
gfs2_trans_end(sdp);
@ -750,9 +768,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
glock_set_object(io_gl, ip);
gfs2_set_iop(inode);
free_vfs_inode = 0; /* After this point, the inode is no longer
considered free. Any failures need to undo
the gfs2 structures. */
if (default_acl) {
error = __gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
if (error)
@ -785,9 +800,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
file->f_mode |= FMODE_CREATED;
error = finish_open(file, dentry, gfs2_open_common);
}
gfs2_glock_dq_uninit(ghs);
gfs2_glock_dq_uninit(&d_gh);
gfs2_qa_put(ip);
gfs2_glock_dq_uninit(ghs + 1);
gfs2_glock_dq_uninit(&gh);
gfs2_glock_put(io_gl);
gfs2_qa_put(dip);
unlock_new_inode(inode);
@ -801,10 +816,6 @@ fail_gunlock3:
fail_gunlock2:
gfs2_glock_put(io_gl);
fail_free_inode:
if (ip->i_gl) {
if (free_vfs_inode) /* else evict will do the put for us */
gfs2_glock_put(ip->i_gl);
}
gfs2_rs_deltree(&ip->i_res);
gfs2_qa_put(ip);
fail_free_acls:
@ -812,20 +823,19 @@ fail_free_acls:
posix_acl_release(acl);
fail_gunlock:
gfs2_dir_no_add(&da);
gfs2_glock_dq_uninit(ghs);
gfs2_glock_dq_uninit(&d_gh);
if (!IS_ERR_OR_NULL(inode)) {
set_bit(GIF_ALLOC_FAILED, &ip->i_flags);
clear_nlink(inode);
if (!free_vfs_inode)
if (ip->i_no_addr)
mark_inode_dirty(inode);
set_bit(free_vfs_inode ? GIF_FREE_VFS_INODE : GIF_ALLOC_FAILED,
&GFS2_I(inode)->i_flags);
if (inode->i_state & I_NEW)
iget_failed(inode);
else
iput(inode);
}
if (gfs2_holder_initialized(ghs + 1))
gfs2_glock_dq_uninit(ghs + 1);
if (gfs2_holder_initialized(&gh))
gfs2_glock_dq_uninit(&gh);
fail:
gfs2_qa_put(dip);
return error;

View File

@ -442,6 +442,12 @@ void gfs2_journal_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
struct buffer_head *bh;
int ty;
if (!ip->i_gl) {
/* This can only happen during incomplete inode creation. */
BUG_ON(!test_bit(GIF_ALLOC_FAILED, &ip->i_flags));
return;
}
gfs2_ail1_wipe(sdp, bstart, blen);
while (blen) {
ty = REMOVE_META;

View File

@ -379,6 +379,7 @@ out:
void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
{
const struct inode *inode = &ip->i_inode;
struct gfs2_dinode *str = buf;
str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
@ -386,15 +387,15 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI);
str->di_num.no_addr = cpu_to_be64(ip->i_no_addr);
str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
str->di_uid = cpu_to_be32(i_uid_read(&ip->i_inode));
str->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode));
str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
str->di_size = cpu_to_be64(i_size_read(&ip->i_inode));
str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec);
str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec);
str->di_mode = cpu_to_be32(inode->i_mode);
str->di_uid = cpu_to_be32(i_uid_read(inode));
str->di_gid = cpu_to_be32(i_gid_read(inode));
str->di_nlink = cpu_to_be32(inode->i_nlink);
str->di_size = cpu_to_be64(i_size_read(inode));
str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(inode));
str->di_atime = cpu_to_be64(inode->i_atime.tv_sec);
str->di_mtime = cpu_to_be64(inode->i_mtime.tv_sec);
str->di_ctime = cpu_to_be64(inode->i_ctime.tv_sec);
str->di_goal_meta = cpu_to_be64(ip->i_goal);
str->di_goal_data = cpu_to_be64(ip->i_goal);
@ -402,16 +403,16 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
str->di_flags = cpu_to_be32(ip->i_diskflags);
str->di_height = cpu_to_be16(ip->i_height);
str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) &&
str->di_payload_format = cpu_to_be32(S_ISDIR(inode->i_mode) &&
!(ip->i_diskflags & GFS2_DIF_EXHASH) ?
GFS2_FORMAT_DE : 0);
str->di_depth = cpu_to_be16(ip->i_depth);
str->di_entries = cpu_to_be32(ip->i_entries);
str->di_eattr = cpu_to_be64(ip->i_eattr);
str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec);
str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec);
str->di_atime_nsec = cpu_to_be32(inode->i_atime.tv_nsec);
str->di_mtime_nsec = cpu_to_be32(inode->i_mtime.tv_nsec);
str->di_ctime_nsec = cpu_to_be32(inode->i_ctime.tv_nsec);
}
/**
@ -475,6 +476,12 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
int need_endtrans = 0;
int ret;
if (unlikely(!ip->i_gl)) {
/* This can only happen during incomplete inode creation. */
BUG_ON(!test_bit(GIF_ALLOC_FAILED, &ip->i_flags));
return;
}
if (unlikely(gfs2_withdrawn(sdp)))
return;
if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
@ -927,8 +934,7 @@ static int gfs2_drop_inode(struct inode *inode)
{
struct gfs2_inode *ip = GFS2_I(inode);
if (!test_bit(GIF_FREE_VFS_INODE, &ip->i_flags) &&
inode->i_nlink &&
if (inode->i_nlink &&
gfs2_holder_initialized(&ip->i_iopen_gh)) {
struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
if (test_bit(GLF_DEMOTE, &gl->gl_flags))
@ -1076,7 +1082,13 @@ static void gfs2_final_release_pages(struct gfs2_inode *ip)
struct inode *inode = &ip->i_inode;
struct gfs2_glock *gl = ip->i_gl;
truncate_inode_pages(gfs2_glock2aspace(ip->i_gl), 0);
if (unlikely(!gl)) {
/* This can only happen during incomplete inode creation. */
BUG_ON(!test_bit(GIF_ALLOC_FAILED, &ip->i_flags));
return;
}
truncate_inode_pages(gfs2_glock2aspace(gl), 0);
truncate_inode_pages(&inode->i_data, 0);
if (atomic_read(&gl->gl_revokes) == 0) {
@ -1218,10 +1230,8 @@ static enum dinode_demise evict_should_delete(struct inode *inode,
struct gfs2_sbd *sdp = sb->s_fs_info;
int ret;
if (test_bit(GIF_ALLOC_FAILED, &ip->i_flags)) {
BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl));
if (unlikely(test_bit(GIF_ALLOC_FAILED, &ip->i_flags)))
goto should_delete;
}
if (test_bit(GIF_DEFERRED_DELETE, &ip->i_flags))
return SHOULD_DEFER_EVICTION;
@ -1294,13 +1304,22 @@ static int evict_unlinked_inode(struct inode *inode)
goto out;
}
/* We're about to clear the bitmap for the dinode, but as soon as we
do, gfs2_create_inode can create another inode at the same block
location and try to set gl_object again. We clear gl_object here so
that subsequent inode creates don't see an old gl_object. */
glock_clear_object(ip->i_gl, ip);
if (ip->i_gl)
gfs2_inode_remember_delete(ip->i_gl, ip->i_no_formal_ino);
/*
* As soon as we clear the bitmap for the dinode, gfs2_create_inode()
* can get called to recreate it, or even gfs2_inode_lookup() if the
* inode was recreated on another node in the meantime.
*
* However, inserting the new inode into the inode hash table will not
* succeed until the old inode is removed, and that only happens after
* ->evict_inode() returns. The new inode is attached to its inode and
* iopen glocks after inserting it into the inode hash table, so at
* that point we can be sure that both glocks are unused.
*/
ret = gfs2_dinode_dealloc(ip);
gfs2_inode_remember_delete(ip->i_gl, ip->i_no_formal_ino);
out:
return ret;
}
@ -1367,12 +1386,7 @@ static void gfs2_evict_inode(struct inode *inode)
struct gfs2_holder gh;
int ret;
if (test_bit(GIF_FREE_VFS_INODE, &ip->i_flags)) {
clear_inode(inode);
return;
}
if (inode->i_nlink || sb_rdonly(sb))
if (inode->i_nlink || sb_rdonly(sb) || !ip->i_no_addr)
goto out;
gfs2_holder_mark_uninitialized(&gh);
@ -1405,12 +1419,9 @@ out:
struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
glock_clear_object(gl, ip);
if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) {
ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
gfs2_glock_dq(&ip->i_iopen_gh);
}
gfs2_glock_hold(gl);
gfs2_holder_uninit(&ip->i_iopen_gh);
ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
gfs2_glock_put_eventually(gl);
}
if (ip->i_gl) {
@ -1429,6 +1440,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
ip = alloc_inode_sb(sb, gfs2_inode_cachep, GFP_KERNEL);
if (!ip)
return NULL;
ip->i_no_addr = 0;
ip->i_flags = 0;
ip->i_gl = NULL;
gfs2_holder_mark_uninitialized(&ip->i_iopen_gh);

View File

@ -1412,11 +1412,13 @@ static int ea_dealloc_block(struct gfs2_inode *ip)
ip->i_eattr = 0;
gfs2_add_inode_blocks(&ip->i_inode, -1);
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
gfs2_trans_add_meta(ip->i_gl, dibh);
gfs2_dinode_out(ip, dibh->b_data);
brelse(dibh);
if (likely(!test_bit(GIF_ALLOC_FAILED, &ip->i_flags))) {
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
gfs2_trans_add_meta(ip->i_gl, dibh);
gfs2_dinode_out(ip, dibh->b_data);
brelse(dibh);
}
}
gfs2_trans_end(sdp);
@ -1445,14 +1447,16 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip)
if (error)
return error;
error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
if (error)
goto out_quota;
if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
error = ea_dealloc_indirect(ip);
if (likely(!test_bit(GIF_ALLOC_FAILED, &ip->i_flags))) {
error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
if (error)
goto out_quota;
if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
error = ea_dealloc_indirect(ip);
if (error)
goto out_quota;
}
}
error = ea_dealloc_block(ip);

View File

@ -0,0 +1,36 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)*/
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Runyang Chen <runyang.chen@mediatek.com>
*/
#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8188
#define _DT_BINDINGS_RESET_CONTROLLER_MT8188
#define MT8188_TOPRGU_CONN_MCU_SW_RST 0
#define MT8188_TOPRGU_INFRA_GRST_SW_RST 1
#define MT8188_TOPRGU_IPU0_SW_RST 2
#define MT8188_TOPRGU_IPU1_SW_RST 3
#define MT8188_TOPRGU_IPU2_SW_RST 4
#define MT8188_TOPRGU_AUD_ASRC_SW_RST 5
#define MT8188_TOPRGU_INFRA_SW_RST 6
#define MT8188_TOPRGU_MMSYS_SW_RST 7
#define MT8188_TOPRGU_MFG_SW_RST 8
#define MT8188_TOPRGU_VENC_SW_RST 9
#define MT8188_TOPRGU_VDEC_SW_RST 10
#define MT8188_TOPRGU_CAM_VCORE_SW_RST 11
#define MT8188_TOPRGU_SCP_SW_RST 12
#define MT8188_TOPRGU_APMIXEDSYS_SW_RST 13
#define MT8188_TOPRGU_AUDIO_SW_RST 14
#define MT8188_TOPRGU_CAMSYS_SW_RST 15
#define MT8188_TOPRGU_MJC_SW_RST 16
#define MT8188_TOPRGU_PERI_SW_RST 17
#define MT8188_TOPRGU_PERI_AO_SW_RST 18
#define MT8188_TOPRGU_PCIE_SW_RST 19
#define MT8188_TOPRGU_ADSPSYS_SW_RST 21
#define MT8188_TOPRGU_DPTX_SW_RST 22
#define MT8188_TOPRGU_SPMI_MST_SW_RST 23
#define MT8188_TOPRGU_SW_RST_NUM 24
#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8188 */

View File

@ -227,6 +227,15 @@
#define RN5T618_WATCHDOG_WDOGTIM_S 0
#define RN5T618_PWRIRQ_IR_WDOG BIT(6)
#define RN5T618_POFFHIS_PWRON BIT(0)
#define RN5T618_POFFHIS_TSHUT BIT(1)
#define RN5T618_POFFHIS_VINDET BIT(2)
#define RN5T618_POFFHIS_IODET BIT(3)
#define RN5T618_POFFHIS_CPU BIT(4)
#define RN5T618_POFFHIS_WDG BIT(5)
#define RN5T618_POFFHIS_DCLIM BIT(6)
#define RN5T618_POFFHIS_N_OE BIT(7)
enum {
RN5T618_DCDC1,
RN5T618_DCDC2,

View File

@ -6,20 +6,6 @@
*
* Contact: Kai Vehmanen <kai.vehmanen@nokia.com>
* Original author: Peter Ujfalusi <peter.ujfalusi@nokia.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.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef _CS_PROTOCOL_H

View File

@ -5,20 +5,6 @@
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
*
* Contact: Andras Domokos <andras.domokos at nokia.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.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __HSI_CHAR_H