summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/drbd/drbd_receiver.c3
-rw-r--r--drivers/block/loop.c28
-rw-r--r--drivers/block/nbd.c1
-rw-r--r--drivers/char/hw_random/powernv-rng.c1
-rw-r--r--drivers/char/hw_random/s390-trng.c1
-rw-r--r--drivers/char/random.c1
-rw-r--r--drivers/firmware/efi/efi.c4
-rw-r--r--drivers/firmware/xilinx/zynqmp.c97
-rw-r--r--drivers/gpio/gpio-mvebu.c9
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi86.c14
-rw-r--r--drivers/hid/Kconfig2
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_client.c4
-rw-r--r--drivers/hid/hid-ids.h4
-rw-r--r--drivers/hid/hid-input.c2
-rw-r--r--drivers/hid/hid-logitech-hidpp.c11
-rw-r--r--drivers/hid/hid-mcp2221.c12
-rw-r--r--drivers/hid/hid-multitouch.c4
-rw-r--r--drivers/hid/hid-plantronics.c9
-rw-r--r--drivers/hid/hid-playstation.c2
-rw-r--r--drivers/hid/hid-sony.c2
-rw-r--r--drivers/hid/wacom_sys.c8
-rw-r--r--drivers/hid/wacom_wac.c4
-rw-r--r--drivers/hid/wacom_wac.h1
-rw-r--r--drivers/input/misc/Kconfig21
-rw-r--r--drivers/input/misc/Makefile2
-rw-r--r--drivers/input/misc/dm355evm_keys.c238
-rw-r--r--drivers/input/misc/tps65219-pwrbutton.c148
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c19
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c13
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c12
-rw-r--r--drivers/leds/rgb/leds-qcom-lpg.c14
-rw-r--r--drivers/mailbox/Kconfig1
-rw-r--r--drivers/mailbox/arm_mhuv2.c4
-rw-r--r--drivers/mailbox/mailbox-mpfs.c31
-rw-r--r--drivers/mailbox/mtk-cmdq-mailbox.c130
-rw-r--r--drivers/mailbox/qcom-apcs-ipc-mailbox.c1
-rw-r--r--drivers/mailbox/rockchip-mailbox.c4
-rw-r--r--drivers/mailbox/zynqmp-ipi-mailbox.c4
-rw-r--r--drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c2
-rw-r--r--drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c2
-rw-r--r--drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c5
-rw-r--r--drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c5
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-api.c1
-rw-r--r--drivers/mfd/88pm800.c10
-rw-r--r--drivers/mfd/88pm805.c7
-rw-r--r--drivers/mfd/88pm80x.c5
-rw-r--r--drivers/mfd/88pm860x-core.c6
-rw-r--r--drivers/mfd/Kconfig69
-rw-r--r--drivers/mfd/Makefile6
-rw-r--r--drivers/mfd/aat2870-core.c13
-rw-r--r--drivers/mfd/act8945a.c5
-rw-r--r--drivers/mfd/adp5520.c12
-rw-r--r--drivers/mfd/arizona-core.c19
-rw-r--r--drivers/mfd/arizona-i2c.c8
-rw-r--r--drivers/mfd/arizona-spi.c2
-rw-r--r--drivers/mfd/as3711.c5
-rw-r--r--drivers/mfd/as3722.c5
-rw-r--r--drivers/mfd/atc260x-core.c6
-rw-r--r--drivers/mfd/atc260x-i2c.c5
-rw-r--r--drivers/mfd/axp20x-i2c.c5
-rw-r--r--drivers/mfd/axp20x.c23
-rw-r--r--drivers/mfd/bcm590xx.c5
-rw-r--r--drivers/mfd/bd9571mwv.c5
-rw-r--r--drivers/mfd/da903x.c6
-rw-r--r--drivers/mfd/da9052-i2c.c6
-rw-r--r--drivers/mfd/da9055-i2c.c5
-rw-r--r--drivers/mfd/da9062-core.c6
-rw-r--r--drivers/mfd/da9063-i2c.c6
-rw-r--r--drivers/mfd/da9150-core.c5
-rw-r--r--drivers/mfd/davinci_voicecodec.c136
-rw-r--r--drivers/mfd/dm355evm_msp.c454
-rw-r--r--drivers/mfd/fsl-imx25-tsadc.c4
-rw-r--r--drivers/mfd/gateworks-gsc.c3
-rw-r--r--drivers/mfd/htc-i2cpld.c627
-rw-r--r--drivers/mfd/khadas-mcu.c5
-rw-r--r--drivers/mfd/lm3533-core.c5
-rw-r--r--drivers/mfd/lp3943.c4
-rw-r--r--drivers/mfd/lp873x.c5
-rw-r--r--drivers/mfd/lp87565.c5
-rw-r--r--drivers/mfd/lp8788.c4
-rw-r--r--drivers/mfd/madera-core.c3
-rw-r--r--drivers/mfd/madera-i2c.c6
-rw-r--r--drivers/mfd/max14577.c19
-rw-r--r--drivers/mfd/max77620.c15
-rw-r--r--drivers/mfd/max77650.c1
-rw-r--r--drivers/mfd/max77686.c6
-rw-r--r--drivers/mfd/max77693.c12
-rw-r--r--drivers/mfd/max77843.c7
-rw-r--r--drivers/mfd/max8907.c5
-rw-r--r--drivers/mfd/max8925-i2c.c12
-rw-r--r--drivers/mfd/max8997.c6
-rw-r--r--drivers/mfd/max8998.c6
-rw-r--r--drivers/mfd/mc13xxx-i2c.c7
-rw-r--r--drivers/mfd/mc13xxx-spi.c3
-rw-r--r--drivers/mfd/mcp-sa11x0.c6
-rw-r--r--drivers/mfd/menelaus.c5
-rw-r--r--drivers/mfd/menf21bmc.c4
-rw-r--r--drivers/mfd/motorola-cpcap.c8
-rw-r--r--drivers/mfd/mt6360-core.c14
-rw-r--r--drivers/mfd/mt6397-irq.c6
-rw-r--r--drivers/mfd/palmas.c13
-rw-r--r--drivers/mfd/pcf50633-core.c27
-rw-r--r--drivers/mfd/pcf50633-irq.c13
-rw-r--r--drivers/mfd/qcom-pm8008.c4
-rw-r--r--drivers/mfd/qcom-pm8xxx.c1
-rw-r--r--drivers/mfd/qcom_rpm.c16
-rw-r--r--drivers/mfd/rc5t583-irq.c7
-rw-r--r--drivers/mfd/rc5t583.c5
-rw-r--r--drivers/mfd/retu-mfd.c4
-rw-r--r--drivers/mfd/rk808.c31
-rw-r--r--drivers/mfd/rn5t618.c3
-rw-r--r--drivers/mfd/rohm-bd71828.c29
-rw-r--r--drivers/mfd/rohm-bd718x7.c27
-rw-r--r--drivers/mfd/rohm-bd9576.c22
-rw-r--r--drivers/mfd/rsmu_i2c.c6
-rw-r--r--drivers/mfd/rt5033.c8
-rw-r--r--drivers/mfd/rt5120.c3
-rw-r--r--drivers/mfd/sec-core.c12
-rw-r--r--drivers/mfd/si476x-i2c.c6
-rw-r--r--drivers/mfd/sky81452.c5
-rw-r--r--drivers/mfd/sm501.c10
-rw-r--r--drivers/mfd/smpro-core.c138
-rw-r--r--drivers/mfd/sprd-sc27xx-spi.c10
-rw-r--r--drivers/mfd/stm32-lptimer.c4
-rw-r--r--drivers/mfd/stmfx.c11
-rw-r--r--drivers/mfd/stmpe-i2c.c9
-rw-r--r--drivers/mfd/stmpe-spi.c4
-rw-r--r--drivers/mfd/stmpe.c8
-rw-r--r--drivers/mfd/stpmic1.c16
-rw-r--r--drivers/mfd/stw481x.c5
-rw-r--r--drivers/mfd/sun4i-gpadc.c3
-rw-r--r--drivers/mfd/t7l66xb.c9
-rw-r--r--drivers/mfd/tc3589x.c13
-rw-r--r--drivers/mfd/tc6387xb.c9
-rw-r--r--drivers/mfd/tc6393xb.c9
-rw-r--r--drivers/mfd/ti-lmu.c5
-rw-r--r--drivers/mfd/timberdale.c1
-rw-r--r--drivers/mfd/tps6105x.c5
-rw-r--r--drivers/mfd/tps65010.c6
-rw-r--r--drivers/mfd/tps6507x.c5
-rw-r--r--drivers/mfd/tps65086.c5
-rw-r--r--drivers/mfd/tps65090.c8
-rw-r--r--drivers/mfd/tps65218.c5
-rw-r--r--drivers/mfd/tps65219.c299
-rw-r--r--drivers/mfd/tps6586x.c11
-rw-r--r--drivers/mfd/tps65910.c6
-rw-r--r--drivers/mfd/tps65912-i2c.c5
-rw-r--r--drivers/mfd/twl-core.c5
-rw-r--r--drivers/mfd/twl6040.c34
-rw-r--r--drivers/mfd/ucb1x00-core.c7
-rw-r--r--drivers/mfd/wcd934x.c11
-rw-r--r--drivers/mfd/wl1273-core.c5
-rw-r--r--drivers/mfd/wm831x-i2c.c6
-rw-r--r--drivers/mfd/wm8350-i2c.c5
-rw-r--r--drivers/mfd/wm8400-core.c5
-rw-r--r--drivers/mfd/wm8994-core.c12
-rw-r--r--drivers/net/bonding/bond_main.c24
-rw-r--r--drivers/net/can/flexcan/flexcan-core.c12
-rw-r--r--drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c33
-rw-r--r--drivers/net/dsa/microchip/ksz_common.c3
-rw-r--r--drivers/net/dsa/mt7530.c3
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c9
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc.c35
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c8
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c2
-rw-r--r--drivers/net/ethernet/intel/igc/igc.h3
-rw-r--r--drivers/net/ethernet/intel/igc/igc_defines.h2
-rw-r--r--drivers/net/ethernet/intel/igc/igc_main.c210
-rw-r--r--drivers/net/ethernet/intel/igc/igc_tsn.c13
-rw-r--r--drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c2
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c1
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_common.c2
-rw-r--r--drivers/net/ethernet/rdc/r6040.c5
-rw-r--r--drivers/net/ethernet/renesas/ravb_main.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c1
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-nuss.c4
-rw-r--r--drivers/net/macsec.c34
-rw-r--r--drivers/net/mctp/mctp-serial.c6
-rw-r--r--drivers/net/wireguard/timers.c8
-rw-r--r--drivers/nfc/pn533/pn533.c4
-rw-r--r--drivers/nvme/host/tcp.c1
-rw-r--r--drivers/pwm/Kconfig6
-rw-r--r--drivers/pwm/core.c68
-rw-r--r--drivers/pwm/pwm-atmel.c6
-rw-r--r--drivers/pwm/pwm-bcm-iproc.c8
-rw-r--r--drivers/pwm/pwm-crc.c10
-rw-r--r--drivers/pwm/pwm-cros-ec.c8
-rw-r--r--drivers/pwm/pwm-dwc.c6
-rw-r--r--drivers/pwm/pwm-fsl-ftm.c18
-rw-r--r--drivers/pwm/pwm-hibvt.c6
-rw-r--r--drivers/pwm/pwm-img.c15
-rw-r--r--drivers/pwm/pwm-imx-tpm.c8
-rw-r--r--drivers/pwm/pwm-imx27.c8
-rw-r--r--drivers/pwm/pwm-intel-lgm.c6
-rw-r--r--drivers/pwm/pwm-iqs620a.c10
-rw-r--r--drivers/pwm/pwm-jz4740.c20
-rw-r--r--drivers/pwm/pwm-keembay.c6
-rw-r--r--drivers/pwm/pwm-lpc18xx-sct.c2
-rw-r--r--drivers/pwm/pwm-lpss.c6
-rw-r--r--drivers/pwm/pwm-mediatek.c9
-rw-r--r--drivers/pwm/pwm-meson.c8
-rw-r--r--drivers/pwm/pwm-mtk-disp.c17
-rw-r--r--drivers/pwm/pwm-pca9685.c13
-rw-r--r--drivers/pwm/pwm-pxa.c58
-rw-r--r--drivers/pwm/pwm-raspberrypi-poe.c8
-rw-r--r--drivers/pwm/pwm-rockchip.c12
-rw-r--r--drivers/pwm/pwm-sifive.c11
-rw-r--r--drivers/pwm/pwm-sl28cpld.c8
-rw-r--r--drivers/pwm/pwm-sprd.c8
-rw-r--r--drivers/pwm/pwm-stm32-lp.c13
-rw-r--r--drivers/pwm/pwm-stm32.c34
-rw-r--r--drivers/pwm/pwm-sun4i.c14
-rw-r--r--drivers/pwm/pwm-sunplus.c6
-rw-r--r--drivers/pwm/pwm-tegra.c15
-rw-r--r--drivers/pwm/pwm-visconti.c6
-rw-r--r--drivers/pwm/pwm-xilinx.c8
-rw-r--r--drivers/remoteproc/Kconfig13
-rw-r--r--drivers/remoteproc/Makefile1
-rw-r--r--drivers/remoteproc/imx_dsp_rproc.c12
-rw-r--r--drivers/remoteproc/imx_rproc.c298
-rw-r--r--drivers/remoteproc/qcom_q6v5_pas.c4
-rw-r--r--drivers/remoteproc/qcom_q6v5_wcss.c6
-rw-r--r--drivers/remoteproc/qcom_sysmon.c13
-rw-r--r--drivers/remoteproc/remoteproc_core.c19
-rw-r--r--drivers/remoteproc/xlnx_r5_remoteproc.c1067
-rw-r--r--drivers/rtc/Kconfig6
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-dm355evm.c151
-rw-r--r--drivers/scsi/iscsi_tcp.c1
-rw-r--r--drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c4
-rw-r--r--drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c6
-rw-r--r--drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c8
-rw-r--r--drivers/usb/usbip/usbip_common.c1
-rw-r--r--drivers/video/backlight/adp8860_bl.c6
-rw-r--r--drivers/video/backlight/adp8870_bl.c6
-rw-r--r--drivers/video/backlight/arcxcnn_bl.c4
-rw-r--r--drivers/video/backlight/bd6107.c5
-rw-r--r--drivers/video/backlight/lm3630a_bl.c5
-rw-r--r--drivers/video/backlight/lm3639_bl.c5
-rw-r--r--drivers/video/backlight/lp855x_bl.c5
-rw-r--r--drivers/video/backlight/lv5207lp.c5
-rw-r--r--drivers/video/backlight/tosa_bl.c5
242 files changed, 3351 insertions, 2688 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 0e58a3187345..757f4692b5bd 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1030,6 +1030,9 @@ randomize:
sock.socket->sk->sk_allocation = GFP_NOIO;
msock.socket->sk->sk_allocation = GFP_NOIO;
+ sock.socket->sk->sk_use_task_frag = false;
+ msock.socket->sk->sk_use_task_frag = false;
+
sock.socket->sk->sk_priority = TC_PRIO_INTERACTIVE_BULK;
msock.socket->sk->sk_priority = TC_PRIO_INTERACTIVE;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 1f8f3b87bdfa..df628e30bca4 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1773,7 +1773,16 @@ static const struct block_device_operations lo_fops = {
/*
* And now the modules code and kernel interface.
*/
-static int max_loop;
+
+/*
+ * If max_loop is specified, create that many devices upfront.
+ * This also becomes a hard limit. If max_loop is not specified,
+ * create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
+ * init time. Loop devices can be requested on-demand with the
+ * /dev/loop-control interface, or be instantiated by accessing
+ * a 'dead' device node.
+ */
+static int max_loop = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
module_param(max_loop, int, 0444);
MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
module_param(max_part, int, 0444);
@@ -2181,7 +2190,7 @@ MODULE_ALIAS("devname:loop-control");
static int __init loop_init(void)
{
- int i, nr;
+ int i;
int err;
part_shift = 0;
@@ -2209,19 +2218,6 @@ static int __init loop_init(void)
goto err_out;
}
- /*
- * If max_loop is specified, create that many devices upfront.
- * This also becomes a hard limit. If max_loop is not specified,
- * create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
- * init time. Loop devices can be requested on-demand with the
- * /dev/loop-control interface, or be instantiated by accessing
- * a 'dead' device node.
- */
- if (max_loop)
- nr = max_loop;
- else
- nr = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
-
err = misc_register(&loop_misc);
if (err < 0)
goto err_out;
@@ -2233,7 +2229,7 @@ static int __init loop_init(void)
}
/* pre-create number of devices given by config or max_loop */
- for (i = 0; i < nr; i++)
+ for (i = 0; i < max_loop; i++)
loop_add(i);
printk(KERN_INFO "loop: module loaded\n");
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index e379ccc63c52..592cfa8b765a 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -512,6 +512,7 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send,
noreclaim_flag = memalloc_noreclaim_save();
do {
sock->sk->sk_allocation = GFP_NOIO | __GFP_MEMALLOC;
+ sock->sk->sk_use_task_frag = false;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
diff --git a/drivers/char/hw_random/powernv-rng.c b/drivers/char/hw_random/powernv-rng.c
index 429e956f34e1..47b88de029f2 100644
--- a/drivers/char/hw_random/powernv-rng.c
+++ b/drivers/char/hw_random/powernv-rng.c
@@ -11,6 +11,7 @@
#include <linux/platform_device.h>
#include <linux/random.h>
#include <linux/hw_random.h>
+#include <asm/archrandom.h>
static int powernv_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
diff --git a/drivers/char/hw_random/s390-trng.c b/drivers/char/hw_random/s390-trng.c
index cffa326ddc8d..d27e32e9bfee 100644
--- a/drivers/char/hw_random/s390-trng.c
+++ b/drivers/char/hw_random/s390-trng.c
@@ -23,6 +23,7 @@
#include <linux/sched/signal.h>
#include <asm/debug.h>
#include <asm/cpacf.h>
+#include <asm/archrandom.h>
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("IBM Corporation");
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 5885ed574c6a..ce3ccd172cc8 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -56,6 +56,7 @@
#include <linux/sched/isolation.h>
#include <crypto/chacha.h>
#include <crypto/blake2s.h>
+#include <asm/archrandom.h>
#include <asm/processor.h>
#include <asm/irq.h>
#include <asm/irq_regs.h>
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 31a4090c66b3..09716eebe8ac 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -429,7 +429,9 @@ static int __init efisubsys_init(void)
platform_device_register_simple("efi_secret", 0, NULL, 0);
#endif
- execute_with_initialized_rng(&refresh_nv_rng_seed_nb);
+ if (efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE))
+ execute_with_initialized_rng(&refresh_nv_rng_seed_nb);
+
return 0;
err_remove_group:
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 6bc6b6c84241..129f68d7a6f5 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1167,6 +1167,103 @@ int zynqmp_pm_release_node(const u32 node)
EXPORT_SYMBOL_GPL(zynqmp_pm_release_node);
/**
+ * zynqmp_pm_get_rpu_mode() - Get RPU mode
+ * @node_id: Node ID of the device
+ * @rpu_mode: return by reference value
+ * either split or lockstep
+ *
+ * Return: return 0 on success or error+reason.
+ * if success, then rpu_mode will be set
+ * to current rpu mode.
+ */
+int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode)
+{
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
+ IOCTL_GET_RPU_OPER_MODE, 0, 0, ret_payload);
+
+ /* only set rpu_mode if no error */
+ if (ret == XST_PM_SUCCESS)
+ *rpu_mode = ret_payload[0];
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_get_rpu_mode);
+
+/**
+ * zynqmp_pm_set_rpu_mode() - Set RPU mode
+ * @node_id: Node ID of the device
+ * @rpu_mode: Argument 1 to requested IOCTL call. either split or lockstep
+ *
+ * This function is used to set RPU mode to split or
+ * lockstep
+ *
+ * Return: Returns status, either success or error+reason
+ */
+int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode)
+{
+ return zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
+ IOCTL_SET_RPU_OPER_MODE, (u32)rpu_mode,
+ 0, NULL);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_set_rpu_mode);
+
+/**
+ * zynqmp_pm_set_tcm_config - configure TCM
+ * @node_id: Firmware specific TCM subsystem ID
+ * @tcm_mode: Argument 1 to requested IOCTL call
+ * either PM_RPU_TCM_COMB or PM_RPU_TCM_SPLIT
+ *
+ * This function is used to set RPU mode to split or combined
+ *
+ * Return: status: 0 for success, else failure
+ */
+int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode)
+{
+ return zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
+ IOCTL_TCM_COMB_CONFIG, (u32)tcm_mode, 0,
+ NULL);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_set_tcm_config);
+
+/**
+ * zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to
+ * be powered down forcefully
+ * @node: Node ID of the targeted PU or subsystem
+ * @ack: Flag to specify whether acknowledge is requested
+ *
+ * Return: status, either success or error+reason
+ */
+int zynqmp_pm_force_pwrdwn(const u32 node,
+ const enum zynqmp_pm_request_ack ack)
+{
+ return zynqmp_pm_invoke_fn(PM_FORCE_POWERDOWN, node, ack, 0, 0, NULL);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_force_pwrdwn);
+
+/**
+ * zynqmp_pm_request_wake - PM call to wake up selected master or subsystem
+ * @node: Node ID of the master or subsystem
+ * @set_addr: Specifies whether the address argument is relevant
+ * @address: Address from which to resume when woken up
+ * @ack: Flag to specify whether acknowledge requested
+ *
+ * Return: status, either success or error+reason
+ */
+int zynqmp_pm_request_wake(const u32 node,
+ const bool set_addr,
+ const u64 address,
+ const enum zynqmp_pm_request_ack ack)
+{
+ /* set_addr flag is encoded into 1st bit of address */
+ return zynqmp_pm_invoke_fn(PM_REQUEST_WAKEUP, node, address | set_addr,
+ address >> 32, ack, NULL);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_request_wake);
+
+/**
* zynqmp_pm_set_requirement() - PM call to set requirement for PM slaves
* @node: Node ID of the slave
* @capabilities: Requested capabilities of the slave
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 1bb317b8dcce..91a4232ee58c 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -657,9 +657,10 @@ static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
spin_unlock_irqrestore(&mvpwm->lock, flags);
}
-static void mvebu_pwm_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state) {
+static int mvebu_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
+{
struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip);
struct mvebu_gpio_chip *mvchip = mvpwm->mvchip;
@@ -693,6 +694,8 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
state->enabled = false;
spin_unlock_irqrestore(&mvpwm->lock, flags);
+
+ return 0;
}
static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index eb24322df721..05f8756d1aaf 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -1500,8 +1500,8 @@ out:
return ret;
}
-static void ti_sn_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int ti_sn_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct ti_sn65dsi86 *pdata = pwm_chip_to_ti_sn_bridge(chip);
unsigned int pwm_en_inv;
@@ -1512,19 +1512,19 @@ static void ti_sn_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
ret = regmap_read(pdata->regmap, SN_PWM_EN_INV_REG, &pwm_en_inv);
if (ret)
- return;
+ return ret;
ret = ti_sn65dsi86_read_u16(pdata, SN_BACKLIGHT_SCALE_REG, &scale);
if (ret)
- return;
+ return ret;
ret = ti_sn65dsi86_read_u16(pdata, SN_BACKLIGHT_REG, &backlight);
if (ret)
- return;
+ return ret;
ret = regmap_read(pdata->regmap, SN_PWM_PRE_DIV_REG, &pre_div);
if (ret)
- return;
+ return ret;
state->enabled = FIELD_GET(SN_PWM_EN_MASK, pwm_en_inv);
if (FIELD_GET(SN_PWM_INV_MASK, pwm_en_inv))
@@ -1539,6 +1539,8 @@ static void ti_sn_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
if (state->duty_cycle > state->period)
state->duty_cycle = state->period;
+
+ return 0;
}
static const struct pwm_ops ti_sn_pwm_ops = {
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 17cce4c50e8d..e2a5d30c8895 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -897,7 +897,7 @@ config HID_PLAYSTATION
select CRC32
select POWER_SUPPLY
help
- Provides support for Sony PS5 controllers including support for
+ Provides support for Sony PS4/PS5 controllers including support for
its special functionalities e.g. touchpad, lights and motion
sensors.
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
index 8275bba63611..ab125f79408f 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
@@ -237,6 +237,10 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
&cl_data->sensor_dma_addr[i],
GFP_KERNEL);
+ if (!in_data->sensor_virt_addr[i]) {
+ rc = -ENOMEM;
+ goto cleanup;
+ }
cl_data->sensor_sts[i] = SENSOR_DISABLED;
cl_data->sensor_requested_cnt[i] = 0;
cl_data->cur_hid_dev = i;
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 8f58c3c1bec3..82713ef3aaa6 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -412,6 +412,7 @@
#define USB_DEVICE_ID_HP_X2_10_COVER 0x0755
#define I2C_DEVICE_ID_HP_ENVY_X360_15 0x2d05
#define I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100 0x29CF
+#define I2C_DEVICE_ID_HP_ENVY_X360_EU0009NV 0x2CF9
#define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817
#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
@@ -995,7 +996,10 @@
#define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S 0x8003
#define USB_VENDOR_ID_PLANTRONICS 0x047f
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES 0xc055
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058
#define USB_VENDOR_ID_PANASONIC 0x04da
#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 3a93cf04147d..9b59e436df0a 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -380,6 +380,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100),
HID_BATTERY_QUIRK_IGNORE },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_EU0009NV),
+ HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15),
HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN),
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index c6e4a96e882e..abf2c95e4d0b 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -2548,12 +2548,17 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
struct hid_device *hid = hidpp->hid_dev;
struct hid_input *hidinput;
struct input_dev *dev;
- const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
- const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
+ struct usb_device_descriptor *udesc;
+ u16 bcdDevice;
struct ff_device *ff;
int error, j, num_slots = data->num_effects;
u8 version;
+ if (!hid_is_usb(hid)) {
+ hid_err(hid, "device is not USB\n");
+ return -ENODEV;
+ }
+
if (list_empty(&hid->inputs)) {
hid_err(hid, "no inputs found\n");
return -ENODEV;
@@ -2567,6 +2572,8 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
}
/* Get firmware release */
+ udesc = &(hid_to_usb_dev(hid)->descriptor);
+ bcdDevice = le16_to_cpu(udesc->bcdDevice);
version = bcdDevice & 255;
/* Set supported force feedback capabilities */
diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
index 5886543b17f3..e61dd039354b 100644
--- a/drivers/hid/hid-mcp2221.c
+++ b/drivers/hid/hid-mcp2221.c
@@ -1110,12 +1110,19 @@ static int mcp2221_probe(struct hid_device *hdev,
return ret;
}
- ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
+ /*
+ * This driver uses the .raw_event callback and therefore does not need any
+ * HID_CONNECT_xxx flags.
+ */
+ ret = hid_hw_start(hdev, 0);
if (ret) {
hid_err(hdev, "can't start hardware\n");
return ret;
}
+ hid_info(hdev, "USB HID v%x.%02x Device [%s] on %s\n", hdev->version >> 8,
+ hdev->version & 0xff, hdev->name, hdev->phys);
+
ret = hid_hw_open(hdev);
if (ret) {
hid_err(hdev, "can't open device\n");
@@ -1145,8 +1152,7 @@ static int mcp2221_probe(struct hid_device *hdev,
mcp->adapter.retries = 1;
mcp->adapter.dev.parent = &hdev->dev;
snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
- "MCP2221 usb-i2c bridge on hidraw%d",
- ((struct hidraw *)hdev->hidraw)->minor);
+ "MCP2221 usb-i2c bridge");
ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter);
if (ret) {
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 91a4d3fc30e0..372cbdd223e0 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1967,6 +1967,10 @@ static const struct hid_device_id mt_devices[] = {
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
USB_VENDOR_ID_ELAN, 0x313a) },
+ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
+ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+ USB_VENDOR_ID_ELAN, 0x3148) },
+
/* Elitegroup panel */
{ .driver_data = MT_CLS_SERIAL,
MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c
index e81b7cec2d12..3d414ae194ac 100644
--- a/drivers/hid/hid-plantronics.c
+++ b/drivers/hid/hid-plantronics.c
@@ -199,8 +199,17 @@ err:
static const struct hid_device_id plantronics_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
+ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
+ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
+ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
{ }
};
diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
index 7b5aef538044..f399bf0d3c8c 100644
--- a/drivers/hid/hid-playstation.c
+++ b/drivers/hid/hid-playstation.c
@@ -1916,7 +1916,7 @@ static int dualshock4_get_mac_address(struct dualshock4 *ds4)
if (ret != sizeof(ds4->base.mac_address))
return -EINVAL;
- ret = 0;
+ return 0;
}
err_free:
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 03691cdcfb8e..13125997ab5e 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -2355,11 +2355,13 @@ static void motion_send_output_report(struct sony_sc *sc)
hid_hw_output_report(hdev, (u8 *)report, MOTION_REPORT_0x02_SIZE);
}
+#ifdef CONFIG_SONY_FF
static inline void sony_send_output_report(struct sony_sc *sc)
{
if (sc->send_output_report)
sc->send_output_report(sc);
}
+#endif
static void sony_state_worker(struct work_struct *work)
{
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 634263e4556b..fb538a6c4add 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -155,6 +155,9 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
{
struct wacom *wacom = hid_get_drvdata(hdev);
+ if (wacom->wacom_wac.features.type == BOOTLOADER)
+ return 0;
+
if (size > WACOM_PKGLEN_MAX)
return 1;
@@ -2785,6 +2788,11 @@ static int wacom_probe(struct hid_device *hdev,
return error;
}
+ if (features->type == BOOTLOADER) {
+ hid_warn(hdev, "Using device in hidraw-only mode");
+ return hid_hw_start(hdev, HID_CONNECT_HIDRAW);
+ }
+
error = wacom_parse_and_register(wacom, false);
if (error)
return error;
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 0f3d57b42684..9312d611db8e 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -4882,6 +4882,9 @@ static const struct wacom_features wacom_features_0x3dd =
static const struct wacom_features wacom_features_HID_ANY_ID =
{ "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
+static const struct wacom_features wacom_features_0x94 =
+ { "Wacom Bootloader", .type = BOOTLOADER };
+
#define USB_DEVICE_WACOM(prod) \
HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
.driver_data = (kernel_ulong_t)&wacom_features_##prod
@@ -4955,6 +4958,7 @@ const struct hid_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x84) },
{ USB_DEVICE_WACOM(0x90) },
{ USB_DEVICE_WACOM(0x93) },
+ { USB_DEVICE_WACOM(0x94) },
{ USB_DEVICE_WACOM(0x97) },
{ USB_DEVICE_WACOM(0x9A) },
{ USB_DEVICE_WACOM(0x9F) },
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 5ca6c06d143b..16f221388563 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -243,6 +243,7 @@ enum {
MTTPC,
MTTPC_B,
HID_GENERIC,
+ BOOTLOADER,
MAX_TYPE
};
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index f3cf189c419b..5c2d0c06d2a5 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -468,6 +468,16 @@ config INPUT_TPS65218_PWRBUTTON
To compile this driver as a module, choose M here. The module will
be called tps65218-pwrbutton.
+config INPUT_TPS65219_PWRBUTTON
+ tristate "TPS65219 Power button driver"
+ depends on MFD_TPS65219
+ help
+ Say Y here if you want to enable power button reporting for
+ TPS65219 Power Management IC devices.
+
+ To compile this driver as a module, choose M here. The module will
+ be called tps65219-pwrbutton.
+
config INPUT_AXP20X_PEK
tristate "X-Powers AXP20X power button driver"
depends on MFD_AXP20X
@@ -662,17 +672,6 @@ config INPUT_DA9063_ONKEY
To compile this driver as a module, choose M here: the module
will be called da9063_onkey.
-config INPUT_DM355EVM
- tristate "TI DaVinci DM355 EVM Keypad and IR Remote"
- depends on MFD_DM355EVM_MSP
- select INPUT_SPARSEKMAP
- help
- Supports the pushbuttons and IR remote used with
- the DM355 EVM board.
-
- To compile this driver as a module, choose M here: the
- module will be called dm355evm_keys.
-
config INPUT_WM831X_ON
tristate "WM831X ON pin"
depends on MFD_WM831X
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 6abefc41037b..61949263300d 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -31,7 +31,6 @@ obj-$(CONFIG_INPUT_DA7280_HAPTICS) += da7280.o
obj-$(CONFIG_INPUT_DA9052_ONKEY) += da9052_onkey.o
obj-$(CONFIG_INPUT_DA9055_ONKEY) += da9055_onkey.o
obj-$(CONFIG_INPUT_DA9063_ONKEY) += da9063_onkey.o
-obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o
obj-$(CONFIG_INPUT_E3X0_BUTTON) += e3x0-button.o
obj-$(CONFIG_INPUT_DRV260X_HAPTICS) += drv260x.o
obj-$(CONFIG_INPUT_DRV2665_HAPTICS) += drv2665.o
@@ -80,6 +79,7 @@ obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
obj-$(CONFIG_INPUT_STPMIC1_ONKEY) += stpmic1_onkey.o
obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON) += tps65218-pwrbutton.o
+obj-$(CONFIG_INPUT_TPS65219_PWRBUTTON) += tps65219-pwrbutton.o
obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
obj-$(CONFIG_INPUT_TWL6040_VIBRA) += twl6040-vibra.o
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c
deleted file mode 100644
index 397ca7c787cc..000000000000
--- a/drivers/input/misc/dm355evm_keys.c
+++ /dev/null
@@ -1,238 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * dm355evm_keys.c - support buttons and IR remote on DM355 EVM board
- *
- * Copyright (c) 2008 by David Brownell
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/input/sparse-keymap.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-
-#include <linux/mfd/dm355evm_msp.h>
-#include <linux/module.h>
-
-
-/*
- * The MSP430 firmware on the DM355 EVM monitors on-board pushbuttons
- * and an IR receptor used for the remote control. When any key is
- * pressed, or its autorepeat kicks in, an event is sent. This driver
- * read those events from the small (32 event) queue and reports them.
- *
- * Note that physically there can only be one of these devices.
- *
- * This driver was tested with firmware revision A4.
- */
-struct dm355evm_keys {
- struct input_dev *input;
- struct device *dev;
-};
-
-/* These initial keycodes can be remapped */
-static const struct key_entry dm355evm_keys[] = {
- /*
- * Pushbuttons on the EVM board ... note that the labels for these
- * are SW10/SW11/etc on the PC board. The left/right orientation
- * comes only from the firmware's documentation, and presumes the
- * power connector is immediately in front of you and the IR sensor
- * is to the right. (That is, rotate the board counter-clockwise
- * by 90 degrees from the SW10/etc and "DM355 EVM" labels.)
- */
- { KE_KEY, 0x00d8, { KEY_OK } }, /* SW12 */
- { KE_KEY, 0x00b8, { KEY_UP } }, /* SW13 */
- { KE_KEY, 0x00e8, { KEY_DOWN } }, /* SW11 */
- { KE_KEY, 0x0078, { KEY_LEFT } }, /* SW14 */
- { KE_KEY, 0x00f0, { KEY_RIGHT } }, /* SW10 */
-
- /*
- * IR buttons ... codes assigned to match the universal remote
- * provided with the EVM (Philips PM4S) using DVD code 0020.
- *
- * These event codes match firmware documentation, but other
- * remote controls could easily send more RC5-encoded events.
- * The PM4S manual was used in several cases to help select
- * a keycode reflecting the intended usage.
- *
- * RC5 codes are 14 bits, with two start bits (0x3 prefix)
- * and a toggle bit (masked out below).
- */
- { KE_KEY, 0x300c, { KEY_POWER } }, /* NOTE: docs omit this */
- { KE_KEY, 0x3000, { KEY_NUMERIC_0 } },
- { KE_KEY, 0x3001, { KEY_NUMERIC_1 } },
- { KE_KEY, 0x3002, { KEY_NUMERIC_2 } },
- { KE_KEY, 0x3003, { KEY_NUMERIC_3 } },
- { KE_KEY, 0x3004, { KEY_NUMERIC_4 } },
- { KE_KEY, 0x3005, { KEY_NUMERIC_5 } },
- { KE_KEY, 0x3006, { KEY_NUMERIC_6 } },
- { KE_KEY, 0x3007, { KEY_NUMERIC_7 } },
- { KE_KEY, 0x3008, { KEY_NUMERIC_8 } },
- { KE_KEY, 0x3009, { KEY_NUMERIC_9 } },
- { KE_KEY, 0x3022, { KEY_ENTER } },
- { KE_KEY, 0x30ec, { KEY_MODE } }, /* "tv/vcr/..." */
- { KE_KEY, 0x300f, { KEY_SELECT } }, /* "info" */
- { KE_KEY, 0x3020, { KEY_CHANNELUP } }, /* "up" */
- { KE_KEY, 0x302e, { KEY_MENU } }, /* "in/out" */
- { KE_KEY, 0x3011, { KEY_VOLUMEDOWN } }, /* "left" */
- { KE_KEY, 0x300d, { KEY_MUTE } }, /* "ok" */
- { KE_KEY, 0x3010, { KEY_VOLUMEUP } }, /* "right" */
- { KE_KEY, 0x301e, { KEY_SUBTITLE } }, /* "cc" */
- { KE_KEY, 0x3021, { KEY_CHANNELDOWN } },/* "down" */
- { KE_KEY, 0x3022, { KEY_PREVIOUS } },
- { KE_KEY, 0x3026, { KEY_SLEEP } },
- { KE_KEY, 0x3172, { KEY_REWIND } }, /* NOTE: docs wrongly say 0x30ca */
- { KE_KEY, 0x3175, { KEY_PLAY } },
- { KE_KEY, 0x3174, { KEY_FASTFORWARD } },
- { KE_KEY, 0x3177, { KEY_RECORD } },
- { KE_KEY, 0x3176, { KEY_STOP } },
- { KE_KEY, 0x3169, { KEY_PAUSE } },
-};
-
-/*
- * Because we communicate with the MSP430 using I2C, and all I2C calls
- * in Linux sleep, we use a threaded IRQ handler. The IRQ itself is
- * active low, but we go through the GPIO controller so we can trigger
- * on falling edges and not worry about enabling/disabling the IRQ in
- * the keypress handling path.
- */
-static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
-{
- static u16 last_event;
- struct dm355evm_keys *keys = _keys;
- const struct key_entry *ke;
- unsigned int keycode;
- int status;
- u16 event;
-
- /* For simplicity we ignore INPUT_COUNT and just read
- * events until we get the "queue empty" indicator.
- * Reading INPUT_LOW decrements the count.
- */
- for (;;) {
- status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH);
- if (status < 0) {
- dev_dbg(keys->dev, "input high err %d\n",
- status);
- break;
- }
- event = status << 8;
-
- status = dm355evm_msp_read(DM355EVM_MSP_INPUT_LOW);
- if (status < 0) {
- dev_dbg(keys->dev, "input low err %d\n",
- status);
- break;
- }
- event |= status;
- if (event == 0xdead)
- break;
-
- /* Press and release a button: two events, same code.
- * Press and hold (autorepeat), then release: N events
- * (N > 2), same code. For RC5 buttons the toggle bits
- * distinguish (for example) "1-autorepeat" from "1 1";
- * but PCB buttons don't support that bit.
- *
- * So we must synthesize release events. We do that by
- * mapping events to a press/release event pair; then
- * to avoid adding extra events, skip the second event
- * of each pair.
- */
- if (event == last_event) {
- last_event = 0;
- continue;
- }
- last_event = event;
-
- /* ignore the RC5 toggle bit */
- event &= ~0x0800;
-
- /* find the key, or report it as unknown */
- ke = sparse_keymap_entry_from_scancode(keys->input, event);
- keycode = ke ? ke->keycode : KEY_UNKNOWN;
- dev_dbg(keys->dev,
- "input event 0x%04x--> keycode %d\n",
- event, keycode);
-
- /* report press + release */
- input_report_key(keys->input, keycode, 1);
- input_sync(keys->input);
- input_report_key(keys->input, keycode, 0);
- input_sync(keys->input);
- }
-
- return IRQ_HANDLED;
-}
-
-/*----------------------------------------------------------------------*/
-
-static int dm355evm_keys_probe(struct platform_device *pdev)
-{
- struct dm355evm_keys *keys;
- struct input_dev *input;
- int irq;
- int error;
-
- keys = devm_kzalloc(&pdev->dev, sizeof (*keys), GFP_KERNEL);
- if (!keys)
- return -ENOMEM;
-
- input = devm_input_allocate_device(&pdev->dev);
- if (!input)
- return -ENOMEM;
-
- keys->dev = &pdev->dev;
- keys->input = input;
-
- input->name = "DM355 EVM Controls";
- input->phys = "dm355evm/input0";
-
- input->id.bustype = BUS_I2C;
- input->id.product = 0x0355;
- input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
-
- error = sparse_keymap_setup(input, dm355evm_keys, NULL);
- if (error)
- return error;
-
- /* REVISIT: flush the event queue? */
-
- /* set up "threaded IRQ handler" */
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- error = devm_request_threaded_irq(&pdev->dev, irq,
- NULL, dm355evm_keys_irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- dev_name(&pdev->dev), keys);
- if (error)
- return error;
-
- /* register */
- error = input_register_device(input);
- if (error)
- return error;
-
- return 0;
-}
-
-/* REVISIT: add suspend/resume when DaVinci supports it. The IRQ should
- * be able to wake up the system. When device_may_wakeup(&pdev->dev), call
- * enable_irq_wake() on suspend, and disable_irq_wake() on resume.
- */
-
-/*
- * I2C is used to talk to the MSP430, but this platform device is
- * exposed by an MFD driver that manages I2C communications.
- */
-static struct platform_driver dm355evm_keys_driver = {
- .probe = dm355evm_keys_probe,
- .driver = {
- .name = "dm355evm_keys",
- },
-};
-module_platform_driver(dm355evm_keys_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/tps65219-pwrbutton.c b/drivers/input/misc/tps65219-pwrbutton.c
new file mode 100644
index 000000000000..245134bdb59e
--- /dev/null
+++ b/drivers/input/misc/tps65219-pwrbutton.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Driver for TPS65219 Push Button
+//
+// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tps65219.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+struct tps65219_pwrbutton {
+ struct device *dev;
+ struct input_dev *idev;
+ char phys[32];
+};
+
+static irqreturn_t tps65219_pb_push_irq(int irq, void *_pwr)
+{
+ struct tps65219_pwrbutton *pwr = _pwr;
+
+ input_report_key(pwr->idev, KEY_POWER, 1);
+ pm_wakeup_event(pwr->dev, 0);
+ input_sync(pwr->idev);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t tps65219_pb_release_irq(int irq, void *_pwr)
+{
+ struct tps65219_pwrbutton *pwr = _pwr;
+
+ input_report_key(pwr->idev, KEY_POWER, 0);
+ input_sync(pwr->idev);
+
+ return IRQ_HANDLED;
+}
+
+static int tps65219_pb_probe(struct platform_device *pdev)
+{
+ struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+ struct device *dev = &pdev->dev;
+ struct tps65219_pwrbutton *pwr;
+ struct input_dev *idev;
+ int error;
+ int push_irq;
+ int release_irq;
+
+ pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL);
+ if (!pwr)
+ return -ENOMEM;
+
+ idev = devm_input_allocate_device(dev);
+ if (!idev)
+ return -ENOMEM;
+
+ idev->name = pdev->name;
+ snprintf(pwr->phys, sizeof(pwr->phys), "%s/input0",
+ pdev->name);
+ idev->phys = pwr->phys;
+ idev->id.bustype = BUS_I2C;
+
+ input_set_capability(idev, EV_KEY, KEY_POWER);
+
+ pwr->dev = dev;
+ pwr->idev = idev;
+ device_init_wakeup(dev, true);
+
+ push_irq = platform_get_irq(pdev, 0);
+ if (push_irq < 0)
+ return -EINVAL;
+
+ release_irq = platform_get_irq(pdev, 1);
+ if (release_irq < 0)
+ return -EINVAL;
+
+ error = devm_request_threaded_irq(dev, push_irq, NULL,
+ tps65219_pb_push_irq,
+ IRQF_ONESHOT,
+ dev->init_name, pwr);
+ if (error) {
+ dev_err(dev, "failed to request push IRQ #%d: %d\n", push_irq,
+ error);
+ return error;
+ }
+
+ error = devm_request_threaded_irq(dev, release_irq, NULL,
+ tps65219_pb_release_irq,
+ IRQF_ONESHOT,
+ dev->init_name, pwr);
+ if (error) {
+ dev_err(dev, "failed to request release IRQ #%d: %d\n",
+ release_irq, error);
+ return error;
+ }
+
+ error = input_register_device(idev);
+ if (error) {
+ dev_err(dev, "Can't register power button: %d\n", error);
+ return error;
+ }
+
+ /* Enable interrupts for the pushbutton */
+ regmap_clear_bits(tps->regmap, TPS65219_REG_MASK_CONFIG,
+ TPS65219_REG_MASK_INT_FOR_PB_MASK);
+
+ /* Set PB/EN/VSENSE pin to be a pushbutton */
+ regmap_update_bits(tps->regmap, TPS65219_REG_MFP_2_CONFIG,
+ TPS65219_MFP_2_EN_PB_VSENSE_MASK, TPS65219_MFP_2_PB);
+
+ return 0;
+}
+
+static int tps65219_pb_remove(struct platform_device *pdev)
+{
+ struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+
+ /* Disable interrupt for the pushbutton */
+ return regmap_update_bits(tps->regmap, TPS65219_REG_MASK_CONFIG,
+ TPS65219_REG_MASK_INT_FOR_PB_MASK,
+ TPS65219_REG_MASK_INT_FOR_PB_MASK);
+}
+
+static const struct platform_device_id tps65219_pwrbtn_id_table[] = {
+ { "tps65219-pwrbutton", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, tps65219_pwrbtn_id_table);
+
+static struct platform_driver tps65219_pb_driver = {
+ .probe = tps65219_pb_probe,
+ .remove = tps65219_pb_remove,
+ .driver = {
+ .name = "tps65219_pwrbutton",
+ },
+ .id_table = tps65219_pwrbtn_id_table,
+};
+module_platform_driver(tps65219_pb_driver);
+
+MODULE_DESCRIPTION("TPS65219 Power Button");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com");
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 4f7eaa17fb27..e840609c50eb 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -3217,6 +3217,7 @@ static int
hfcm_l1callback(struct dchannel *dch, u_int cmd)
{
struct hfc_multi *hc = dch->hw;
+ struct sk_buff_head free_queue;
u_long flags;
switch (cmd) {
@@ -3245,6 +3246,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
l1_event(dch->l1, HW_POWERUP_IND);
break;
case HW_DEACT_REQ:
+ __skb_queue_head_init(&free_queue);
/* start deactivation */
spin_lock_irqsave(&hc->lock, flags);
if (hc->ctype == HFC_TYPE_E1) {
@@ -3264,20 +3266,21 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
plxsd_checksync(hc, 0);
}
}
- skb_queue_purge(&dch->squeue);
+ skb_queue_splice_init(&dch->squeue, &free_queue);
if (dch->tx_skb) {
- dev_kfree_skb(dch->tx_skb);
+ __skb_queue_tail(&free_queue, dch->tx_skb);
dch->tx_skb = NULL;
}
dch->tx_idx = 0;
if (dch->rx_skb) {
- dev_kfree_skb(dch->rx_skb);
+ __skb_queue_tail(&free_queue, dch->rx_skb);
dch->rx_skb = NULL;
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
del_timer(&dch->timer);
spin_unlock_irqrestore(&hc->lock, flags);
+ __skb_queue_purge(&free_queue);
break;
case HW_POWERUP_REQ:
spin_lock_irqsave(&hc->lock, flags);
@@ -3384,6 +3387,9 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
case PH_DEACTIVATE_REQ:
test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
if (dch->dev.D.protocol != ISDN_P_TE_S0) {
+ struct sk_buff_head free_queue;
+
+ __skb_queue_head_init(&free_queue);
spin_lock_irqsave(&hc->lock, flags);
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG
@@ -3405,14 +3411,14 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
/* deactivate */
dch->state = 1;
}
- skb_queue_purge(&dch->squeue);
+ skb_queue_splice_init(&dch->squeue, &free_queue);
if (dch->tx_skb) {
- dev_kfree_skb(dch->tx_skb);
+ __skb_queue_tail(&free_queue, dch->tx_skb);
dch->tx_skb = NULL;
}
dch->tx_idx = 0;
if (dch->rx_skb) {
- dev_kfree_skb(dch->rx_skb);
+ __skb_queue_tail(&free_queue, dch->rx_skb);
dch->rx_skb = NULL;
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
@@ -3424,6 +3430,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
#endif
ret = 0;
spin_unlock_irqrestore(&hc->lock, flags);
+ __skb_queue_purge(&free_queue);
} else
ret = l1_event(dch->l1, hh->prim);
break;
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index e964a8dd8512..c0331b268010 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -1617,16 +1617,19 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
spin_lock_irqsave(&hc->lock, flags);
if (hc->hw.protocol == ISDN_P_NT_S0) {
+ struct sk_buff_head free_queue;
+
+ __skb_queue_head_init(&free_queue);
/* prepare deactivation */
Write_hfc(hc, HFCPCI_STATES, 0x40);
- skb_queue_purge(&dch->squeue);
+ skb_queue_splice_init(&dch->squeue, &free_queue);
if (dch->tx_skb) {
- dev_kfree_skb(dch->tx_skb);
+ __skb_queue_tail(&free_queue, dch->tx_skb);
dch->tx_skb = NULL;
}
dch->tx_idx = 0;
if (dch->rx_skb) {
- dev_kfree_skb(dch->rx_skb);
+ __skb_queue_tail(&free_queue, dch->rx_skb);
dch->rx_skb = NULL;
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
@@ -1639,10 +1642,12 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
hc->hw.mst_m &= ~HFCPCI_MASTER;
Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
ret = 0;
+ spin_unlock_irqrestore(&hc->lock, flags);
+ __skb_queue_purge(&free_queue);
} else {
ret = l1_event(dch->l1, hh->prim);
+ spin_unlock_irqrestore(&hc->lock, flags);
}
- spin_unlock_irqrestore(&hc->lock, flags);
break;
}
if (!ret)
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index 651f2f8f685b..1efd17979f24 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -326,20 +326,24 @@ hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
if (hw->protocol == ISDN_P_NT_S0) {
+ struct sk_buff_head free_queue;
+
+ __skb_queue_head_init(&free_queue);
hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);
spin_lock_irqsave(&hw->lock, flags);
- skb_queue_purge(&dch->squeue);
+ skb_queue_splice_init(&dch->squeue, &free_queue);
if (dch->tx_skb) {
- dev_kfree_skb(dch->tx_skb);
+ __skb_queue_tail(&free_queue, dch->tx_skb);
dch->tx_skb = NULL;
}
dch->tx_idx = 0;
if (dch->rx_skb) {
- dev_kfree_skb(dch->rx_skb);
+ __skb_queue_tail(&free_queue, dch->rx_skb);
dch->rx_skb = NULL;
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
spin_unlock_irqrestore(&hw->lock, flags);
+ __skb_queue_purge(&free_queue);
#ifdef FIXME
if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
dchannel_sched_event(&hc->dch, D_CLEARBUSY);
@@ -1330,7 +1334,7 @@ tx_iso_complete(struct urb *urb)
printk("\n");
}
- dev_kfree_skb(tx_skb);
+ dev_consume_skb_irq(tx_skb);
tx_skb = NULL;
if (fifo->dch && get_next_dframe(fifo->dch))
tx_skb = fifo->dch->tx_skb;
diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
index c1a56259226f..67f48f222109 100644
--- a/drivers/leds/rgb/leds-qcom-lpg.c
+++ b/drivers/leds/rgb/leds-qcom-lpg.c
@@ -972,8 +972,8 @@ out_unlock:
return ret;
}
-static void lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct lpg *lpg = container_of(chip, struct lpg, pwm);
struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
@@ -986,20 +986,20 @@ static void lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
ret = regmap_read(lpg->map, chan->base + LPG_SIZE_CLK_REG, &val);
if (ret)
- return;
+ return ret;
refclk = lpg_clk_rates[val & PWM_CLK_SELECT_MASK];
if (refclk) {
ret = regmap_read(lpg->map, chan->base + LPG_PREDIV_CLK_REG, &val);
if (ret)
- return;
+ return ret;
pre_div = lpg_pre_divs[FIELD_GET(PWM_FREQ_PRE_DIV_MASK, val)];
m = FIELD_GET(PWM_FREQ_EXP_MASK, val);
ret = regmap_bulk_read(lpg->map, chan->base + PWM_VALUE_REG, &pwm_value, sizeof(pwm_value));
if (ret)
- return;
+ return ret;
state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * LPG_RESOLUTION * pre_div * (1 << m), refclk);
state->duty_cycle = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pwm_value * pre_div * (1 << m), refclk);
@@ -1010,13 +1010,15 @@ static void lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
ret = regmap_read(lpg->map, chan->base + PWM_ENABLE_CONTROL_REG, &val);
if (ret)
- return;
+ return ret;
state->enabled = FIELD_GET(LPG_ENABLE_CONTROL_OUTPUT, val);
state->polarity = PWM_POLARITY_NORMAL;
if (state->duty_cycle > state->period)
state->duty_cycle = state->period;
+
+ return 0;
}
static const struct pwm_ops lpg_pwm_ops = {
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d7af896cbd7b..1495965bc394 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -136,6 +136,7 @@ config STI_MBOX
config TI_MESSAGE_MANAGER
tristate "Texas Instruments Message Manager Driver"
depends on ARCH_KEYSTONE || ARCH_K3
+ default ARCH_K3
help
An implementation of Message Manager slave driver for Keystone
and K3 architecture SoCs from Texas Instruments. Message Manager
diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c
index a47aef8df52f..c6d4957c4da8 100644
--- a/drivers/mailbox/arm_mhuv2.c
+++ b/drivers/mailbox/arm_mhuv2.c
@@ -1062,8 +1062,8 @@ static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
int ret = -EINVAL;
reg = devm_of_iomap(dev, dev->of_node, 0, NULL);
- if (!reg)
- return -ENOMEM;
+ if (IS_ERR(reg))
+ return PTR_ERR(reg);
mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
if (!mhu)
diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
index cfacb3f320a6..853901acaeec 100644
--- a/drivers/mailbox/mailbox-mpfs.c
+++ b/drivers/mailbox/mailbox-mpfs.c
@@ -2,7 +2,7 @@
/*
* Microchip PolarFire SoC (MPFS) system controller/mailbox controller driver
*
- * Copyright (c) 2020 Microchip Corporation. All rights reserved.
+ * Copyright (c) 2020-2022 Microchip Corporation. All rights reserved.
*
* Author: Conor Dooley <conor.dooley@microchip.com>
*
@@ -56,7 +56,7 @@
#define SCB_STATUS_NOTIFY_MASK BIT(SCB_STATUS_NOTIFY)
#define SCB_STATUS_POS (16)
-#define SCB_STATUS_MASK GENMASK_ULL(SCB_STATUS_POS + SCB_MASK_WIDTH, SCB_STATUS_POS)
+#define SCB_STATUS_MASK GENMASK(SCB_STATUS_POS + SCB_MASK_WIDTH - 1, SCB_STATUS_POS)
struct mpfs_mbox {
struct mbox_controller controller;
@@ -130,13 +130,38 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)
struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
struct mpfs_mss_response *response = mbox->response;
u16 num_words = ALIGN((response->resp_size), (4)) / 4U;
- u32 i;
+ u32 i, status;
if (!response->resp_msg) {
dev_err(mbox->dev, "failed to assign memory for response %d\n", -ENOMEM);
return;
}
+ /*
+ * The status is stored in bits 31:16 of the SERVICES_SR register.
+ * It is only valid when BUSY == 0.
+ * We should *never* get an interrupt while the controller is
+ * still in the busy state. If we do, something has gone badly
+ * wrong & the content of the mailbox would not be valid.
+ */
+ if (mpfs_mbox_busy(mbox)) {
+ dev_err(mbox->dev, "got an interrupt but system controller is busy\n");
+ response->resp_status = 0xDEAD;
+ return;
+ }
+
+ status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
+
+ /*
+ * If the status of the individual servers is non-zero, the service has
+ * failed. The contents of the mailbox at this point are not be valid,
+ * so don't bother reading them. Set the status so that the driver
+ * implementing the service can handle the result.
+ */
+ response->resp_status = (status & SCB_STATUS_MASK) >> SCB_STATUS_POS;
+ if (response->resp_status)
+ return;
+
if (!mpfs_mbox_busy(mbox)) {
for (i = 0; i < num_words; i++) {
response->resp_msg[i] =
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 9465f9081515..b18d47ea13a0 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -38,6 +38,8 @@
#define CMDQ_THR_PRIORITY 0x40
#define GCE_GCTL_VALUE 0x48
+#define GCE_CTRL_BY_SW GENMASK(2, 0)
+#define GCE_DDR_EN GENMASK(18, 16)
#define CMDQ_THR_ACTIVE_SLOT_CYCLES 0x3200
#define CMDQ_THR_ENABLED 0x1
@@ -73,28 +75,38 @@ struct cmdq {
struct mbox_controller mbox;
void __iomem *base;
int irq;
- u32 thread_nr;
u32 irq_mask;
+ const struct gce_plat *pdata;
struct cmdq_thread *thread;
struct clk_bulk_data clocks[CMDQ_GCE_NUM_MAX];
bool suspended;
- u8 shift_pa;
- bool control_by_sw;
- u32 gce_num;
};
struct gce_plat {
u32 thread_nr;
u8 shift;
bool control_by_sw;
+ bool sw_ddr_en;
u32 gce_num;
};
+static void cmdq_sw_ddr_enable(struct cmdq *cmdq, bool enable)
+{
+ WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
+
+ if (enable)
+ writel(GCE_DDR_EN | GCE_CTRL_BY_SW, cmdq->base + GCE_GCTL_VALUE);
+ else
+ writel(GCE_CTRL_BY_SW, cmdq->base + GCE_GCTL_VALUE);
+
+ clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
+}
+
u8 cmdq_get_shift_pa(struct mbox_chan *chan)
{
struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
- return cmdq->shift_pa;
+ return cmdq->pdata->shift;
}
EXPORT_SYMBOL(cmdq_get_shift_pa);
@@ -126,14 +138,21 @@ static void cmdq_thread_resume(struct cmdq_thread *thread)
static void cmdq_init(struct cmdq *cmdq)
{
int i;
+ u32 gctl_regval = 0;
+
+ WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
+ if (cmdq->pdata->control_by_sw)
+ gctl_regval = GCE_CTRL_BY_SW;
+ if (cmdq->pdata->sw_ddr_en)
+ gctl_regval |= GCE_DDR_EN;
+
+ if (gctl_regval)
+ writel(gctl_regval, cmdq->base + GCE_GCTL_VALUE);
- WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
- if (cmdq->control_by_sw)
- writel(0x7, cmdq->base + GCE_GCTL_VALUE);
writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
for (i = 0; i <= CMDQ_MAX_EVENT; i++)
writel(i, cmdq->base + CMDQ_SYNC_TOKEN_UPDATE);
- clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+ clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
}
static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread *thread)
@@ -178,7 +197,7 @@ static void cmdq_task_insert_into_thread(struct cmdq_task *task)
prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] =
(u64)CMDQ_JUMP_BY_PA << 32 |
- (task->pa_base >> task->cmdq->shift_pa);
+ (task->pa_base >> task->cmdq->pdata->shift);
dma_sync_single_for_device(dev, prev_task->pa_base,
prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
@@ -212,7 +231,7 @@ static void cmdq_task_handle_error(struct cmdq_task *task)
next_task = list_first_entry_or_null(&thread->task_busy_list,
struct cmdq_task, list_entry);
if (next_task)
- writel(next_task->pa_base >> cmdq->shift_pa,
+ writel(next_task->pa_base >> cmdq->pdata->shift,
thread->base + CMDQ_THR_CURR_ADDR);
cmdq_thread_resume(thread);
}
@@ -243,7 +262,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
else
return;
- curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->shift_pa;
+ curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->pdata->shift;
list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
list_entry) {
@@ -266,7 +285,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
if (list_empty(&thread->task_busy_list)) {
cmdq_thread_disable(cmdq, thread);
- clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+ clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
}
}
@@ -280,7 +299,7 @@ static irqreturn_t cmdq_irq_handler(int irq, void *dev)
if (!(irq_status ^ cmdq->irq_mask))
return IRQ_NONE;
- for_each_clear_bit(bit, &irq_status, cmdq->thread_nr) {
+ for_each_clear_bit(bit, &irq_status, cmdq->pdata->thread_nr) {
struct cmdq_thread *thread = &cmdq->thread[bit];
spin_lock_irqsave(&thread->chan->lock, flags);
@@ -300,7 +319,7 @@ static int cmdq_suspend(struct device *dev)
cmdq->suspended = true;
- for (i = 0; i < cmdq->thread_nr; i++) {
+ for (i = 0; i < cmdq->pdata->thread_nr; i++) {
thread = &cmdq->thread[i];
if (!list_empty(&thread->task_busy_list)) {
task_running = true;
@@ -311,7 +330,10 @@ static int cmdq_suspend(struct device *dev)
if (task_running)
dev_warn(dev, "exist running task(s) in suspend\n");
- clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
+ if (cmdq->pdata->sw_ddr_en)
+ cmdq_sw_ddr_enable(cmdq, false);
+
+ clk_bulk_unprepare(cmdq->pdata->gce_num, cmdq->clocks);
return 0;
}
@@ -320,8 +342,12 @@ static int cmdq_resume(struct device *dev)
{
struct cmdq *cmdq = dev_get_drvdata(dev);
- WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
+ WARN_ON(clk_bulk_prepare(cmdq->pdata->gce_num, cmdq->clocks));
cmdq->suspended = false;
+
+ if (cmdq->pdata->sw_ddr_en)
+ cmdq_sw_ddr_enable(cmdq, true);
+
return 0;
}
@@ -329,7 +355,10 @@ static int cmdq_remove(struct platform_device *pdev)
{
struct cmdq *cmdq = platform_get_drvdata(pdev);
- clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
+ if (cmdq->pdata->sw_ddr_en)
+ cmdq_sw_ddr_enable(cmdq, false);
+
+ clk_bulk_unprepare(cmdq->pdata->gce_num, cmdq->clocks);
return 0;
}
@@ -355,7 +384,7 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
task->pkt = pkt;
if (list_empty(&thread->task_busy_list)) {
- WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
+ WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
/*
* The thread reset will clear thread related register to 0,
@@ -365,9 +394,9 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
*/
WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
- writel(task->pa_base >> cmdq->shift_pa,
+ writel(task->pa_base >> cmdq->pdata->shift,
thread->base + CMDQ_THR_CURR_ADDR);
- writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
+ writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->pdata->shift,
thread->base + CMDQ_THR_END_ADDR);
writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
@@ -376,20 +405,20 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
} else {
WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
- cmdq->shift_pa;
+ cmdq->pdata->shift;
end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
- cmdq->shift_pa;
+ cmdq->pdata->shift;
/* check boundary */
if (curr_pa == end_pa - CMDQ_INST_SIZE ||
curr_pa == end_pa) {
/* set to this task directly */
- writel(task->pa_base >> cmdq->shift_pa,
+ writel(task->pa_base >> cmdq->pdata->shift,
thread->base + CMDQ_THR_CURR_ADDR);
} else {
cmdq_task_insert_into_thread(task);
smp_mb(); /* modify jump before enable thread */
}
- writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
+ writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->pdata->shift,
thread->base + CMDQ_THR_END_ADDR);
cmdq_thread_resume(thread);
}
@@ -428,7 +457,7 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
}
cmdq_thread_disable(cmdq, thread);
- clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+ clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
done:
/*
@@ -468,7 +497,7 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
cmdq_thread_resume(thread);
cmdq_thread_disable(cmdq, thread);
- clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+ clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
out:
spin_unlock_irqrestore(&thread->chan->lock, flags);
@@ -515,7 +544,6 @@ static int cmdq_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct cmdq *cmdq;
int err, i;
- struct gce_plat *plat_data;
struct device_node *phandle = dev->of_node;
struct device_node *node;
int alias_id = 0;
@@ -534,31 +562,21 @@ static int cmdq_probe(struct platform_device *pdev)
if (cmdq->irq < 0)
return cmdq->irq;
- plat_data = (struct gce_plat *)of_device_get_match_data(dev);
- if (!plat_data) {
+ cmdq->pdata = device_get_match_data(dev);
+ if (!cmdq->pdata) {
dev_err(dev, "failed to get match data\n");
return -EINVAL;
}
- cmdq->thread_nr = plat_data->thread_nr;
- cmdq->shift_pa = plat_data->shift;
- cmdq->control_by_sw = plat_data->control_by_sw;
- cmdq->gce_num = plat_data->gce_num;
- cmdq->irq_mask = GENMASK(cmdq->thread_nr - 1, 0);
- err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
- "mtk_cmdq", cmdq);
- if (err < 0) {
- dev_err(dev, "failed to register ISR (%d)\n", err);
- return err;
- }
+ cmdq->irq_mask = GENMASK(cmdq->pdata->thread_nr - 1, 0);
dev_dbg(dev, "cmdq device: addr:0x%p, va:0x%p, irq:%d\n",
dev, cmdq->base, cmdq->irq);
- if (cmdq->gce_num > 1) {
+ if (cmdq->pdata->gce_num > 1) {
for_each_child_of_node(phandle->parent, node) {
alias_id = of_alias_get_id(node, clk_name);
- if (alias_id >= 0 && alias_id < cmdq->gce_num) {
+ if (alias_id >= 0 && alias_id < cmdq->pdata->gce_num) {
cmdq->clocks[alias_id].id = clk_names[alias_id];
cmdq->clocks[alias_id].clk = of_clk_get(node, 0);
if (IS_ERR(cmdq->clocks[alias_id].clk)) {
@@ -580,12 +598,12 @@ static int cmdq_probe(struct platform_device *pdev)
}
cmdq->mbox.dev = dev;
- cmdq->mbox.chans = devm_kcalloc(dev, cmdq->thread_nr,
+ cmdq->mbox.chans = devm_kcalloc(dev, cmdq->pdata->thread_nr,
sizeof(*cmdq->mbox.chans), GFP_KERNEL);
if (!cmdq->mbox.chans)
return -ENOMEM;
- cmdq->mbox.num_chans = cmdq->thread_nr;
+ cmdq->mbox.num_chans = cmdq->pdata->thread_nr;
cmdq->mbox.ops = &cmdq_mbox_chan_ops;
cmdq->mbox.of_xlate = cmdq_xlate;
@@ -593,12 +611,12 @@ static int cmdq_probe(struct platform_device *pdev)
cmdq->mbox.txdone_irq = false;
cmdq->mbox.txdone_poll = false;
- cmdq->thread = devm_kcalloc(dev, cmdq->thread_nr,
+ cmdq->thread = devm_kcalloc(dev, cmdq->pdata->thread_nr,
sizeof(*cmdq->thread), GFP_KERNEL);
if (!cmdq->thread)
return -ENOMEM;
- for (i = 0; i < cmdq->thread_nr; i++) {
+ for (i = 0; i < cmdq->pdata->thread_nr; i++) {
cmdq->thread[i].base = cmdq->base + CMDQ_THR_BASE +
CMDQ_THR_SIZE * i;
INIT_LIST_HEAD(&cmdq->thread[i].task_busy_list);
@@ -613,10 +631,17 @@ static int cmdq_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, cmdq);
- WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
+ WARN_ON(clk_bulk_prepare(cmdq->pdata->gce_num, cmdq->clocks));
cmdq_init(cmdq);
+ err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
+ "mtk_cmdq", cmdq);
+ if (err < 0) {
+ dev_err(dev, "failed to register ISR (%d)\n", err);
+ return err;
+ }
+
return 0;
}
@@ -660,9 +685,18 @@ static const struct gce_plat gce_plat_v6 = {
.gce_num = 2
};
+static const struct gce_plat gce_plat_v7 = {
+ .thread_nr = 24,
+ .shift = 3,
+ .control_by_sw = true,
+ .sw_ddr_en = true,
+ .gce_num = 1
+};
+
static const struct of_device_id cmdq_of_ids[] = {
{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
+ {.compatible = "mediatek,mt8186-gce", .data = (void *)&gce_plat_v7},
{.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
{.compatible = "mediatek,mt8192-gce", .data = (void *)&gce_plat_v5},
{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v6},
diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
index f1f0e87a79e6..0e9f9cba8668 100644
--- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c
+++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
@@ -156,6 +156,7 @@ static const struct of_device_id qcom_apcs_ipc_of_match[] = {
{ .compatible = "qcom,sc8180x-apss-shared", .data = &apps_shared_apcs_data },
{ .compatible = "qcom,sdm660-apcs-hmss-global", .data = &msm8994_apcs_data },
{ .compatible = "qcom,sdm845-apss-shared", .data = &apps_shared_apcs_data },
+ { .compatible = "qcom,sm4250-apcs-hmss-global", .data = &msm8994_apcs_data },
{ .compatible = "qcom,sm6125-apcs-hmss-global", .data = &msm8994_apcs_data },
{ .compatible = "qcom,sm8150-apss-shared", .data = &apps_shared_apcs_data },
{ .compatible = "qcom,sm6115-apcs-hmss-global", .data = &msm8994_apcs_data },
diff --git a/drivers/mailbox/rockchip-mailbox.c b/drivers/mailbox/rockchip-mailbox.c
index 979acc810f30..e02d3c9e3693 100644
--- a/drivers/mailbox/rockchip-mailbox.c
+++ b/drivers/mailbox/rockchip-mailbox.c
@@ -164,7 +164,6 @@ MODULE_DEVICE_TABLE(of, rockchp_mbox_of_match);
static int rockchip_mbox_probe(struct platform_device *pdev)
{
struct rockchip_mbox *mb;
- const struct of_device_id *match;
const struct rockchip_mbox_data *drv_data;
struct resource *res;
int ret, irq, i;
@@ -172,8 +171,7 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
if (!pdev->dev.of_node)
return -ENODEV;
- match = of_match_node(rockchip_mbox_of_match, pdev->dev.of_node);
- drv_data = (const struct rockchip_mbox_data *)match->data;
+ drv_data = (const struct rockchip_mbox_data *) device_get_match_data(&pdev->dev);
mb = devm_kzalloc(&pdev->dev, sizeof(*mb), GFP_KERNEL);
if (!mb)
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index 31a0fa914274..12e004ff1a14 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -493,6 +493,7 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
ret = device_register(&ipi_mbox->dev);
if (ret) {
dev_err(dev, "Failed to register ipi mbox dev.\n");
+ put_device(&ipi_mbox->dev);
return ret;
}
mdev = &ipi_mbox->dev;
@@ -619,7 +620,8 @@ static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)
ipi_mbox = &pdata->ipi_mboxes[i];
if (ipi_mbox->dev.parent) {
mbox_controller_unregister(&ipi_mbox->mbox);
- device_unregister(&ipi_mbox->dev);
+ if (device_is_registered(&ipi_mbox->dev))
+ device_unregister(&ipi_mbox->dev);
}
}
}
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
index ebfc870d2af5..4db950973ce2 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
@@ -663,7 +663,7 @@ sun6i_csi_bridge_notifier_bound(struct v4l2_async_notifier *notifier,
enabled = !bridge->source_parallel.expected;
break;
default:
- break;
+ return -EINVAL;
}
source->subdev = remote_subdev;
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index 6d34f5c0768f..cf6aadbc130b 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -832,7 +832,7 @@ static int sun6i_csi_capture_open(struct file *file)
{
struct sun6i_csi_device *csi_dev = video_drvdata(file);
struct sun6i_csi_capture *capture = &csi_dev->capture;
- int ret = 0;
+ int ret;
if (mutex_lock_interruptible(&capture->lock))
return -ERESTARTSYS;
diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
index 484ac5f054d5..a220ce849b41 100644
--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
@@ -188,7 +188,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
return -ENODEV;
if (!on) {
- ret = v4l2_subdev_call(source_subdev, video, s_stream, 0);
+ v4l2_subdev_call(source_subdev, video, s_stream, 0);
+ ret = 0;
goto disable;
}
@@ -280,8 +281,6 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
return 0;
disable:
- if (!on)
- ret = 0;
phy_power_off(dphy);
sun6i_mipi_csi2_disable(csi2_dev);
diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
index d993c09a4820..cd2e92ae2293 100644
--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
@@ -220,7 +220,8 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
return -ENODEV;
if (!on) {
- ret = v4l2_subdev_call(source_subdev, video, s_stream, 0);
+ v4l2_subdev_call(source_subdev, video, s_stream, 0);
+ ret = 0;
goto disable;
}
@@ -312,8 +313,6 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
return 0;
disable:
- if (!on)
- ret = 0;
phy_power_off(dphy);
sun8i_a83t_mipi_csi2_disable(csi2_dev);
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c
index d0a3aa3806fb..3d3b6dc24ca6 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
@@ -150,6 +150,7 @@ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
* then return an error.
*/
if (strlen(ctrl->p_new.p_char) == ctrl->maximum && last)
+ ctrl->is_new = 1;
return -ERANGE;
}
return ret;
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index a30e47b74327..4d9b61b92754 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -398,9 +398,8 @@ static struct regmap_irq_chip pm800_irq_chip = {
.num_regs = 4,
.status_base = PM800_INT_STATUS1,
- .mask_base = PM800_INT_ENA_1,
+ .unmask_base = PM800_INT_ENA_1,
.ack_base = PM800_INT_STATUS1,
- .mask_invert = 1,
};
static int pm800_pages_init(struct pm80x_chip *chip)
@@ -528,8 +527,7 @@ out:
return ret;
}
-static int pm800_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int pm800_probe(struct i2c_client *client)
{
int ret = 0;
struct pm80x_chip *chip;
@@ -597,9 +595,9 @@ static void pm800_remove(struct i2c_client *client)
static struct i2c_driver pm800_driver = {
.driver = {
.name = "88PM800",
- .pm = &pm80x_pm_ops,
+ .pm = pm_sleep_ptr(&pm80x_pm_ops),
},
- .probe = pm800_probe,
+ .probe_new = pm800_probe,
.remove = pm800_remove,
.id_table = pm80x_id_table,
};
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c
index 10d3637840c8..352f13cb1481 100644
--- a/drivers/mfd/88pm805.c
+++ b/drivers/mfd/88pm805.c
@@ -209,8 +209,7 @@ out_irq_init:
return ret;
}
-static int pm805_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int pm805_probe(struct i2c_client *client)
{
int ret = 0;
struct pm80x_chip *chip;
@@ -252,9 +251,9 @@ static void pm805_remove(struct i2c_client *client)
static struct i2c_driver pm805_driver = {
.driver = {
.name = "88PM805",
- .pm = &pm80x_pm_ops,
+ .pm = pm_sleep_ptr(&pm80x_pm_ops),
},
- .probe = pm805_probe,
+ .probe_new = pm805_probe,
.remove = pm805_remove,
.id_table = pm80x_id_table,
};
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
index be036e7e787b..ac4f08565f29 100644
--- a/drivers/mfd/88pm80x.c
+++ b/drivers/mfd/88pm80x.c
@@ -129,7 +129,6 @@ int pm80x_deinit(void)
}
EXPORT_SYMBOL_GPL(pm80x_deinit);
-#ifdef CONFIG_PM_SLEEP
static int pm80x_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -153,10 +152,8 @@ static int pm80x_resume(struct device *dev)
return 0;
}
-#endif
-SIMPLE_DEV_PM_OPS(pm80x_pm_ops, pm80x_suspend, pm80x_resume);
-EXPORT_SYMBOL_GPL(pm80x_pm_ops);
+EXPORT_GPL_SIMPLE_DEV_PM_OPS(pm80x_pm_ops, pm80x_suspend, pm80x_resume);
MODULE_DESCRIPTION("I2C Driver for Marvell 88PM80x");
MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 5dc86dd66202..6ba7169cb953 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -1212,7 +1212,6 @@ static void pm860x_remove(struct i2c_client *client)
}
}
-#ifdef CONFIG_PM_SLEEP
static int pm860x_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -1232,9 +1231,8 @@ static int pm860x_resume(struct device *dev)
disable_irq_wake(chip->core_irq);
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
static const struct i2c_device_id pm860x_id_table[] = {
{ "88PM860x", 0 },
@@ -1251,7 +1249,7 @@ MODULE_DEVICE_TABLE(of, pm860x_dt_ids);
static struct i2c_driver pm860x_driver = {
.driver = {
.name = "88PM860x",
- .pm = &pm860x_pm_ops,
+ .pm = pm_sleep_ptr(&pm860x_pm_ops),
.of_match_table = pm860x_dt_ids,
},
.probe_new = pm860x_probe,
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8b93856de432..30db49f31866 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -77,6 +77,18 @@ config MFD_AS3711
help
Support for the AS3711 PMIC from AMS
+config MFD_SMPRO
+ tristate "Ampere Computing SMpro core driver"
+ depends on I2C
+ select MFD_CORE
+ select REGMAP_I2C
+ help
+ Say yes here to enable SMpro driver support for Ampere's Altra
+ processor family.
+
+ Ampere's Altra SMpro exposes an I2C regmap interface that can
+ be accessed by child devices.
+
config MFD_AS3722
tristate "ams AS3722 Power Management IC"
select MFD_CORE
@@ -547,15 +559,6 @@ config HTC_PASIC3
HTC Magician devices, respectively. Actual functionality is
handled by the leds-pasic3 and ds1wm drivers.
-config HTC_I2CPLD
- bool "HTC I2C PLD chip support"
- depends on I2C=y && GPIOLIB
- help
- If you say yes here you get support for the supposed CPLD
- found on omap850 HTC devices like the HTC Wizard and HTC Herald.
- This device provides input and output GPIOs through an I2C
- interface to one or more sub-chips.
-
config MFD_INTEL_QUARK_I2C_GPIO
tristate "Intel Quark MFD I2C GPIO"
depends on PCI
@@ -591,7 +594,7 @@ config INTEL_SOC_PMIC
bool "Support for Crystal Cove PMIC"
depends on HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK
depends on (X86 && ACPI) || COMPILE_TEST
- depends on I2C_DESIGNWARE_PLATFORM=y
+ depends on I2C_DESIGNWARE_PLATFORM=y || COMPILE_TEST
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -794,7 +797,7 @@ config MFD_MAX14577
config MFD_MAX77620
bool "Maxim Semiconductor MAX77620 and MAX20024 PMIC Support"
depends on I2C=y
- depends on OF || COMPILE_TEST
+ depends on OF
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -809,7 +812,7 @@ config MFD_MAX77620
config MFD_MAX77650
tristate "Maxim MAX77650/77651 PMIC Support"
depends on I2C
- depends on OF || COMPILE_TEST
+ depends on OF
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -824,7 +827,7 @@ config MFD_MAX77650
config MFD_MAX77686
tristate "Maxim Semiconductor MAX77686/802 PMIC Support"
depends on I2C
- depends on OF || COMPILE_TEST
+ depends on OF
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -853,7 +856,7 @@ config MFD_MAX77693
config MFD_MAX77714
tristate "Maxim Semiconductor MAX77714 PMIC Support"
depends on I2C
- depends on OF || COMPILE_TEST
+ depends on OF
select MFD_CORE
select REGMAP_I2C
help
@@ -1010,7 +1013,7 @@ config EZX_PCAP
config MFD_CPCAP
tristate "Support for Motorola CPCAP"
depends on SPI
- depends on OF || COMPILE_TEST
+ depends on OF
select MFD_CORE
select REGMAP_SPI
select REGMAP_IRQ
@@ -1035,7 +1038,7 @@ config MFD_VIPERBOARD
config MFD_NTXEC
tristate "Netronix embedded controller (EC)"
- depends on OF || COMPILE_TEST
+ depends on OF
depends on I2C
select REGMAP_I2C
select MFD_CORE
@@ -1231,7 +1234,7 @@ config MFD_RN5T618
config MFD_SEC_CORE
tristate "Samsung Electronics PMIC Series Support"
depends on I2C=y
- depends on OF || COMPILE_TEST
+ depends on OF
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -1432,11 +1435,6 @@ config MFD_SYSCON
Select this option to enable accessing system control registers
via regmap.
-config MFD_DAVINCI_VOICECODEC
- tristate
- select MFD_CORE
- select REGMAP_MMIO
-
config MFD_TI_AM335X_TSCADC
tristate "TI ADC / Touch Screen chip support"
select MFD_CORE
@@ -1448,14 +1446,6 @@ config MFD_TI_AM335X_TSCADC
To compile this driver as a module, choose M here: the
module will be called ti_am335x_tscadc.
-config MFD_DM355EVM_MSP
- bool "TI DaVinci DM355 EVM microcontroller"
- depends on I2C=y && MACH_DAVINCI_DM355_EVM
- help
- This driver supports the MSP430 microcontroller used on these
- boards. MSP430 firmware manages resets and power sequencing,
- inputs from buttons and the IR remote, LEDs, an RTC, and more.
-
config MFD_LP3943
tristate "TI/National Semiconductor LP3943 MFD Driver"
depends on I2C
@@ -1499,7 +1489,7 @@ config MFD_OMAP_USB_HOST
OMAP USB Host drivers.
config MFD_PALMAS
- bool "TI Palmas series chips"
+ tristate "TI Palmas series chips"
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -1635,6 +1625,20 @@ config MFD_TPS65218
This driver can also be built as a module. If so, the module
will be called tps65218.
+config MFD_TPS65219
+ tristate "TI TPS65219 Power Management IC"
+ depends on I2C && OF
+ select MFD_CORE
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ help
+ If you say yes here you get support for the TPS65219 series of Power
+ Management ICs. These include voltage regulators, GPIOs and
+ push/power button that is often used in portable devices.
+
+ This driver can also be built as a module. If so, the module
+ will be called tps65219.
+
config MFD_TPS6586X
bool "TI TPS6586x Power Management chips"
depends on I2C=y
@@ -2027,6 +2031,7 @@ config MFD_ROHM_BD957XMUF
depends on I2C=y
depends on OF
select REGMAP_I2C
+ select REGMAP_IRQ
select MFD_CORE
help
Select this option to get support for the ROHM BD9576MUF and
@@ -2077,7 +2082,7 @@ config MFD_STPMIC1
config MFD_STMFX
tristate "Support for STMicroelectronics Multi-Function eXpander (STMFX)"
depends on I2C
- depends on OF || COMPILE_TEST
+ depends on OF
select MFD_CORE
select REGMAP_I2C
help
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 7ed3ef4a698c..457471478a93 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -19,13 +19,9 @@ obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
obj-$(CONFIG_MFD_GATEWORKS_GSC) += gateworks-gsc.o
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
-obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
obj-$(CONFIG_MFD_TI_LP873X) += lp873x.o
obj-$(CONFIG_MFD_TI_LP87565) += lp87565.o
-
-obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
-obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o
obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o
@@ -101,6 +97,7 @@ obj-$(CONFIG_TPS6507X) += tps6507x.o
obj-$(CONFIG_MFD_TPS65086) += tps65086.o
obj-$(CONFIG_MFD_TPS65217) += tps65217.o
obj-$(CONFIG_MFD_TPS65218) += tps65218.o
+obj-$(CONFIG_MFD_TPS65219) += tps65219.o
obj-$(CONFIG_MFD_TPS65910) += tps65910.o
obj-$(CONFIG_MFD_TPS65912) += tps65912-core.o
obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o
@@ -271,6 +268,7 @@ obj-$(CONFIG_MFD_QCOM_PM8008) += qcom-pm8008.o
obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o
obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o
+obj-$(CONFIG_MFD_SMPRO) += smpro-core.o
obj-$(CONFIG_MFD_INTEL_M10_BMC) += intel-m10-bmc.o
obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c
index a17cf759739d..f253da5b246b 100644
--- a/drivers/mfd/aat2870-core.c
+++ b/drivers/mfd/aat2870-core.c
@@ -332,8 +332,7 @@ static inline void aat2870_init_debugfs(struct aat2870_data *aat2870)
}
#endif /* CONFIG_DEBUG_FS */
-static int aat2870_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int aat2870_i2c_probe(struct i2c_client *client)
{
struct aat2870_platform_data *pdata = dev_get_platdata(&client->dev);
struct aat2870_data *aat2870;
@@ -409,7 +408,6 @@ out_disable:
return ret;
}
-#ifdef CONFIG_PM_SLEEP
static int aat2870_i2c_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -438,10 +436,9 @@ static int aat2870_i2c_resume(struct device *dev)
return 0;
}
-#endif /* CONFIG_PM_SLEEP */
-static SIMPLE_DEV_PM_OPS(aat2870_pm_ops, aat2870_i2c_suspend,
- aat2870_i2c_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(aat2870_pm_ops, aat2870_i2c_suspend,
+ aat2870_i2c_resume);
static const struct i2c_device_id aat2870_i2c_id_table[] = {
{ "aat2870", 0 },
@@ -451,10 +448,10 @@ static const struct i2c_device_id aat2870_i2c_id_table[] = {
static struct i2c_driver aat2870_i2c_driver = {
.driver = {
.name = "aat2870",
- .pm = &aat2870_pm_ops,
+ .pm = pm_sleep_ptr(&aat2870_pm_ops),
.suppress_bind_attrs = true,
},
- .probe = aat2870_i2c_probe,
+ .probe_new = aat2870_i2c_probe,
.id_table = aat2870_i2c_id_table,
};
diff --git a/drivers/mfd/act8945a.c b/drivers/mfd/act8945a.c
index d3520430997c..bcf0fda15f0c 100644
--- a/drivers/mfd/act8945a.c
+++ b/drivers/mfd/act8945a.c
@@ -28,8 +28,7 @@ static const struct regmap_config act8945a_regmap_config = {
.val_bits = 8,
};
-static int act8945a_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int act8945a_i2c_probe(struct i2c_client *i2c)
{
int ret;
struct regmap *regmap;
@@ -71,7 +70,7 @@ static struct i2c_driver act8945a_i2c_driver = {
.name = "act8945a",
.of_match_table = of_match_ptr(act8945a_of_match),
},
- .probe = act8945a_i2c_probe,
+ .probe_new = act8945a_i2c_probe,
.id_table = act8945a_i2c_id,
};
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
index 8db15f5a7179..cb168efdbafe 100644
--- a/drivers/mfd/adp5520.c
+++ b/drivers/mfd/adp5520.c
@@ -204,9 +204,9 @@ static int adp5520_remove_subdevs(struct adp5520_chip *chip)
return device_for_each_child(chip->dev, NULL, __remove_subdev);
}
-static int adp5520_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int adp5520_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct adp5520_platform_data *pdata = dev_get_platdata(&client->dev);
struct platform_device *pdev;
struct adp5520_chip *chip;
@@ -305,7 +305,6 @@ out_free_irq:
return ret;
}
-#ifdef CONFIG_PM_SLEEP
static int adp5520_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -326,9 +325,8 @@ static int adp5520_resume(struct device *dev)
adp5520_write(chip->dev, ADP5520_MODE_STATUS, chip->mode);
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(adp5520_pm, adp5520_suspend, adp5520_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(adp5520_pm, adp5520_suspend, adp5520_resume);
static const struct i2c_device_id adp5520_id[] = {
{ "pmic-adp5520", ID_ADP5520 },
@@ -339,10 +337,10 @@ static const struct i2c_device_id adp5520_id[] = {
static struct i2c_driver adp5520_driver = {
.driver = {
.name = "adp5520",
- .pm = &adp5520_pm,
+ .pm = pm_sleep_ptr(&adp5520_pm),
.suppress_bind_attrs = true,
},
- .probe = adp5520_probe,
+ .probe_new = adp5520_probe,
.id_table = adp5520_id,
};
builtin_i2c_driver(adp5520_driver);
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index cbf1dd90b70d..bd7ee3260d53 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -480,7 +480,6 @@ static int wm5102_clear_write_sequencer(struct arizona *arizona)
return 0;
}
-#ifdef CONFIG_PM
static int arizona_isolate_dcvdd(struct arizona *arizona)
{
int ret;
@@ -742,9 +741,7 @@ static int arizona_runtime_suspend(struct device *dev)
return 0;
}
-#endif
-#ifdef CONFIG_PM_SLEEP
static int arizona_suspend(struct device *dev)
{
struct arizona *arizona = dev_get_drvdata(dev);
@@ -784,17 +781,15 @@ static int arizona_resume(struct device *dev)
return 0;
}
-#endif
-const struct dev_pm_ops arizona_pm_ops = {
- SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
- arizona_runtime_resume,
- NULL)
- SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(arizona_suspend_noirq,
- arizona_resume_noirq)
+EXPORT_GPL_DEV_PM_OPS(arizona_pm_ops) = {
+ RUNTIME_PM_OPS(arizona_runtime_suspend,
+ arizona_runtime_resume,
+ NULL)
+ SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
+ NOIRQ_SYSTEM_SLEEP_PM_OPS(arizona_suspend_noirq,
+ arizona_resume_noirq)
};
-EXPORT_SYMBOL_GPL(arizona_pm_ops);
#ifdef CONFIG_OF
static int arizona_of_get_core_pdata(struct arizona *arizona)
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c
index bfc7cf56ff2c..b2301586adbc 100644
--- a/drivers/mfd/arizona-i2c.c
+++ b/drivers/mfd/arizona-i2c.c
@@ -20,9 +20,9 @@
#include "arizona.h"
-static int arizona_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int arizona_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
const void *match_data;
struct arizona *arizona;
const struct regmap_config *regmap_config = NULL;
@@ -117,10 +117,10 @@ static const struct of_device_id arizona_i2c_of_match[] = {
static struct i2c_driver arizona_i2c_driver = {
.driver = {
.name = "arizona",
- .pm = &arizona_pm_ops,
+ .pm = pm_ptr(&arizona_pm_ops),
.of_match_table = of_match_ptr(arizona_i2c_of_match),
},
- .probe = arizona_i2c_probe,
+ .probe_new = arizona_i2c_probe,
.remove = arizona_i2c_remove,
.id_table = arizona_i2c_id,
};
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index 941b0267d09d..da05b966d48c 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -282,7 +282,7 @@ static const struct of_device_id arizona_spi_of_match[] = {
static struct spi_driver arizona_spi_driver = {
.driver = {
.name = "arizona",
- .pm = &arizona_pm_ops,
+ .pm = pm_ptr(&arizona_pm_ops),
.of_match_table = of_match_ptr(arizona_spi_of_match),
.acpi_match_table = ACPI_PTR(arizona_acpi_match),
},
diff --git a/drivers/mfd/as3711.c b/drivers/mfd/as3711.c
index 3adaec6c37df..3facfdd28e81 100644
--- a/drivers/mfd/as3711.c
+++ b/drivers/mfd/as3711.c
@@ -116,8 +116,7 @@ static const struct of_device_id as3711_of_match[] = {
};
#endif
-static int as3711_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int as3711_i2c_probe(struct i2c_client *client)
{
struct as3711 *as3711;
struct as3711_platform_data *pdata;
@@ -202,7 +201,7 @@ static struct i2c_driver as3711_i2c_driver = {
.name = "as3711",
.of_match_table = of_match_ptr(as3711_of_match),
},
- .probe = as3711_i2c_probe,
+ .probe_new = as3711_i2c_probe,
.id_table = as3711_i2c_id,
};
diff --git a/drivers/mfd/as3722.c b/drivers/mfd/as3722.c
index 38665efae4f0..b6dda0eb8645 100644
--- a/drivers/mfd/as3722.c
+++ b/drivers/mfd/as3722.c
@@ -333,8 +333,7 @@ static int as3722_i2c_of_probe(struct i2c_client *i2c,
return 0;
}
-static int as3722_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int as3722_i2c_probe(struct i2c_client *i2c)
{
struct as3722 *as3722;
unsigned long irq_flags;
@@ -446,7 +445,7 @@ static struct i2c_driver as3722_i2c_driver = {
.of_match_table = as3722_of_match,
.pm = &as3722_pm_ops,
},
- .probe = as3722_i2c_probe,
+ .probe_new = as3722_i2c_probe,
.id_table = as3722_i2c_id,
};
diff --git a/drivers/mfd/atc260x-core.c b/drivers/mfd/atc260x-core.c
index 7148ff5b05b1..7c5de3ae776e 100644
--- a/drivers/mfd/atc260x-core.c
+++ b/drivers/mfd/atc260x-core.c
@@ -100,8 +100,7 @@ static const struct regmap_irq_chip atc2603c_regmap_irq_chip = {
.num_irqs = ARRAY_SIZE(atc2603c_regmap_irqs),
.num_regs = 1,
.status_base = ATC2603C_INTS_PD,
- .mask_base = ATC2603C_INTS_MSK,
- .mask_invert = true,
+ .unmask_base = ATC2603C_INTS_MSK,
};
static const struct regmap_irq_chip atc2609a_regmap_irq_chip = {
@@ -110,8 +109,7 @@ static const struct regmap_irq_chip atc2609a_regmap_irq_chip = {
.num_irqs = ARRAY_SIZE(atc2609a_regmap_irqs),
.num_regs = 1,
.status_base = ATC2609A_INTS_PD,
- .mask_base = ATC2609A_INTS_MSK,
- .mask_invert = true,
+ .unmask_base = ATC2609A_INTS_MSK,
};
static const struct resource atc2603c_onkey_resources[] = {
diff --git a/drivers/mfd/atc260x-i2c.c b/drivers/mfd/atc260x-i2c.c
index 5855efd09efc..19e248ed7966 100644
--- a/drivers/mfd/atc260x-i2c.c
+++ b/drivers/mfd/atc260x-i2c.c
@@ -12,8 +12,7 @@
#include <linux/of.h>
#include <linux/regmap.h>
-static int atc260x_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int atc260x_i2c_probe(struct i2c_client *client)
{
struct atc260x *atc260x;
struct regmap_config regmap_cfg;
@@ -54,7 +53,7 @@ static struct i2c_driver atc260x_i2c_driver = {
.name = "atc260x",
.of_match_table = of_match_ptr(atc260x_i2c_of_match),
},
- .probe = atc260x_i2c_probe,
+ .probe_new = atc260x_i2c_probe,
};
module_i2c_driver(atc260x_i2c_driver);
diff --git a/drivers/mfd/axp20x-i2c.c b/drivers/mfd/axp20x-i2c.c
index 8fd6727dc30a..f49fbd307958 100644
--- a/drivers/mfd/axp20x-i2c.c
+++ b/drivers/mfd/axp20x-i2c.c
@@ -22,8 +22,7 @@
#include <linux/regmap.h>
#include <linux/slab.h>
-static int axp20x_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int axp20x_i2c_probe(struct i2c_client *i2c)
{
struct axp20x_dev *axp20x;
int ret;
@@ -100,7 +99,7 @@ static struct i2c_driver axp20x_i2c_driver = {
.of_match_table = of_match_ptr(axp20x_i2c_of_match),
.acpi_match_table = ACPI_PTR(axp20x_i2c_acpi_match),
},
- .probe = axp20x_i2c_probe,
+ .probe_new = axp20x_i2c_probe,
.remove = axp20x_i2c_remove,
.id_table = axp20x_i2c_id,
};
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 88a212a8168c..47fd700f284f 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -506,8 +506,7 @@ static const struct regmap_irq_chip axp152_regmap_irq_chip = {
.name = "axp152_irq_chip",
.status_base = AXP152_IRQ1_STATE,
.ack_base = AXP152_IRQ1_STATE,
- .mask_base = AXP152_IRQ1_EN,
- .mask_invert = true,
+ .unmask_base = AXP152_IRQ1_EN,
.init_ack_masked = true,
.irqs = axp152_regmap_irqs,
.num_irqs = ARRAY_SIZE(axp152_regmap_irqs),
@@ -518,8 +517,7 @@ static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
.name = "axp20x_irq_chip",
.status_base = AXP20X_IRQ1_STATE,
.ack_base = AXP20X_IRQ1_STATE,
- .mask_base = AXP20X_IRQ1_EN,
- .mask_invert = true,
+ .unmask_base = AXP20X_IRQ1_EN,
.init_ack_masked = true,
.irqs = axp20x_regmap_irqs,
.num_irqs = ARRAY_SIZE(axp20x_regmap_irqs),
@@ -531,8 +529,7 @@ static const struct regmap_irq_chip axp22x_regmap_irq_chip = {
.name = "axp22x_irq_chip",
.status_base = AXP20X_IRQ1_STATE,
.ack_base = AXP20X_IRQ1_STATE,
- .mask_base = AXP20X_IRQ1_EN,
- .mask_invert = true,
+ .unmask_base = AXP20X_IRQ1_EN,
.init_ack_masked = true,
.irqs = axp22x_regmap_irqs,
.num_irqs = ARRAY_SIZE(axp22x_regmap_irqs),
@@ -543,8 +540,7 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
.name = "axp288_irq_chip",
.status_base = AXP20X_IRQ1_STATE,
.ack_base = AXP20X_IRQ1_STATE,
- .mask_base = AXP20X_IRQ1_EN,
- .mask_invert = true,
+ .unmask_base = AXP20X_IRQ1_EN,
.init_ack_masked = true,
.irqs = axp288_regmap_irqs,
.num_irqs = ARRAY_SIZE(axp288_regmap_irqs),
@@ -556,8 +552,7 @@ static const struct regmap_irq_chip axp803_regmap_irq_chip = {
.name = "axp803",
.status_base = AXP20X_IRQ1_STATE,
.ack_base = AXP20X_IRQ1_STATE,
- .mask_base = AXP20X_IRQ1_EN,
- .mask_invert = true,
+ .unmask_base = AXP20X_IRQ1_EN,
.init_ack_masked = true,
.irqs = axp803_regmap_irqs,
.num_irqs = ARRAY_SIZE(axp803_regmap_irqs),
@@ -568,8 +563,7 @@ static const struct regmap_irq_chip axp806_regmap_irq_chip = {
.name = "axp806",
.status_base = AXP20X_IRQ1_STATE,
.ack_base = AXP20X_IRQ1_STATE,
- .mask_base = AXP20X_IRQ1_EN,
- .mask_invert = true,
+ .unmask_base = AXP20X_IRQ1_EN,
.init_ack_masked = true,
.irqs = axp806_regmap_irqs,
.num_irqs = ARRAY_SIZE(axp806_regmap_irqs),
@@ -580,8 +574,7 @@ static const struct regmap_irq_chip axp809_regmap_irq_chip = {
.name = "axp809",
.status_base = AXP20X_IRQ1_STATE,
.ack_base = AXP20X_IRQ1_STATE,
- .mask_base = AXP20X_IRQ1_EN,
- .mask_invert = true,
+ .unmask_base = AXP20X_IRQ1_EN,
.init_ack_masked = true,
.irqs = axp809_regmap_irqs,
.num_irqs = ARRAY_SIZE(axp809_regmap_irqs),
@@ -842,7 +835,7 @@ static void axp20x_power_off(void)
AXP20X_OFF);
/* Give capacitors etc. time to drain to avoid kernel panic msg. */
- msleep(500);
+ mdelay(500);
}
int axp20x_match_device(struct axp20x_dev *axp20x)
diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c
index 6ca337cde84c..251d515478d5 100644
--- a/drivers/mfd/bcm590xx.c
+++ b/drivers/mfd/bcm590xx.c
@@ -38,8 +38,7 @@ static const struct regmap_config bcm590xx_regmap_config_sec = {
.cache_type = REGCACHE_RBTREE,
};
-static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri,
- const struct i2c_device_id *id)
+static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri)
{
struct bcm590xx *bcm590xx;
int ret;
@@ -109,7 +108,7 @@ static struct i2c_driver bcm590xx_i2c_driver = {
.name = "bcm590xx",
.of_match_table = bcm590xx_of_match,
},
- .probe = bcm590xx_i2c_probe,
+ .probe_new = bcm590xx_i2c_probe,
.id_table = bcm590xx_i2c_id,
};
module_i2c_driver(bcm590xx_i2c_driver);
diff --git a/drivers/mfd/bd9571mwv.c b/drivers/mfd/bd9571mwv.c
index e15b1acfb063..60dc858c8117 100644
--- a/drivers/mfd/bd9571mwv.c
+++ b/drivers/mfd/bd9571mwv.c
@@ -204,8 +204,7 @@ static int bd957x_identify(struct device *dev, struct regmap *regmap)
return 0;
}
-static int bd9571mwv_probe(struct i2c_client *client,
- const struct i2c_device_id *ids)
+static int bd9571mwv_probe(struct i2c_client *client)
{
const struct regmap_config *regmap_config;
const struct regmap_irq_chip *irq_chip;
@@ -279,7 +278,7 @@ static struct i2c_driver bd9571mwv_driver = {
.name = "bd9571mwv",
.of_match_table = bd9571mwv_of_match_table,
},
- .probe = bd9571mwv_probe,
+ .probe_new = bd9571mwv_probe,
.id_table = bd9571mwv_id_table,
};
module_i2c_driver(bd9571mwv_driver);
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index 3f8f6ad3a98c..44a25d642ce9 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -488,9 +488,9 @@ failed:
return ret;
}
-static int da903x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int da903x_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct da903x_platform_data *pdata = dev_get_platdata(&client->dev);
struct da903x_chip *chip;
unsigned int tmp;
@@ -543,7 +543,7 @@ static struct i2c_driver da903x_driver = {
.driver = {
.name = "da903x",
},
- .probe = da903x_probe,
+ .probe_new = da903x_probe,
.remove = da903x_remove,
.id_table = da903x_id_table,
};
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c
index 5a74696c8704..ecb8077cdaaf 100644
--- a/drivers/mfd/da9052-i2c.c
+++ b/drivers/mfd/da9052-i2c.c
@@ -126,9 +126,9 @@ static const struct of_device_id dialog_dt_ids[] = {
};
#endif
-static int da9052_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int da9052_i2c_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct da9052 *da9052;
int ret;
@@ -176,7 +176,7 @@ static void da9052_i2c_remove(struct i2c_client *client)
}
static struct i2c_driver da9052_i2c_driver = {
- .probe = da9052_i2c_probe,
+ .probe_new = da9052_i2c_probe,
.remove = da9052_i2c_remove,
.id_table = da9052_i2c_id,
.driver = {
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c
index 276c7d1c509e..702abff506a1 100644
--- a/drivers/mfd/da9055-i2c.c
+++ b/drivers/mfd/da9055-i2c.c
@@ -15,8 +15,7 @@
#include <linux/mfd/da9055/core.h>
-static int da9055_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int da9055_i2c_probe(struct i2c_client *i2c)
{
struct da9055 *da9055;
int ret;
@@ -67,7 +66,7 @@ static const struct of_device_id da9055_of_match[] = {
};
static struct i2c_driver da9055_i2c_driver = {
- .probe = da9055_i2c_probe,
+ .probe_new = da9055_i2c_probe,
.remove = da9055_i2c_remove,
.id_table = da9055_i2c_id,
.driver = {
diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c
index a26e473507c7..40cde51e5719 100644
--- a/drivers/mfd/da9062-core.c
+++ b/drivers/mfd/da9062-core.c
@@ -621,9 +621,9 @@ static const struct of_device_id da9062_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, da9062_dt_ids);
-static int da9062_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int da9062_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct da9062 *chip;
unsigned int irq_base;
const struct mfd_cell *cell;
@@ -744,7 +744,7 @@ static struct i2c_driver da9062_i2c_driver = {
.name = "da9062",
.of_match_table = da9062_dt_ids,
},
- .probe = da9062_i2c_probe,
+ .probe_new = da9062_i2c_probe,
.remove = da9062_i2c_remove,
.id_table = da9062_i2c_id,
};
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
index 343ed6e96d87..03f8f95a1d62 100644
--- a/drivers/mfd/da9063-i2c.c
+++ b/drivers/mfd/da9063-i2c.c
@@ -351,9 +351,9 @@ static const struct of_device_id da9063_dt_ids[] = {
{ }
};
MODULE_DEVICE_TABLE(of, da9063_dt_ids);
-static int da9063_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int da9063_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct da9063 *da9063;
int ret;
@@ -469,7 +469,7 @@ static struct i2c_driver da9063_i2c_driver = {
.name = "da9063",
.of_match_table = da9063_dt_ids,
},
- .probe = da9063_i2c_probe,
+ .probe_new = da9063_i2c_probe,
.id_table = da9063_i2c_id,
};
diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c
index 6ae56e46d24e..d2c954103b2f 100644
--- a/drivers/mfd/da9150-core.c
+++ b/drivers/mfd/da9150-core.c
@@ -392,8 +392,7 @@ static struct mfd_cell da9150_devs[] = {
},
};
-static int da9150_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int da9150_probe(struct i2c_client *client)
{
struct da9150 *da9150;
struct da9150_pdata *pdata = dev_get_platdata(&client->dev);
@@ -511,7 +510,7 @@ static struct i2c_driver da9150_driver = {
.name = "da9150",
.of_match_table = da9150_of_match,
},
- .probe = da9150_probe,
+ .probe_new = da9150_probe,
.remove = da9150_remove,
.shutdown = da9150_shutdown,
.id_table = da9150_i2c_id,
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c
deleted file mode 100644
index 965820481f1e..000000000000
--- a/drivers/mfd/davinci_voicecodec.c
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * DaVinci Voice Codec Core Interface for TI platforms
- *
- * Copyright (C) 2010 Texas Instruments, Inc
- *
- * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/regmap.h>
-
-#include <sound/pcm.h>
-
-#include <linux/mfd/davinci_voicecodec.h>
-
-static const struct regmap_config davinci_vc_regmap = {
- .reg_bits = 32,
- .val_bits = 32,
-};
-
-static int __init davinci_vc_probe(struct platform_device *pdev)
-{
- struct davinci_vc *davinci_vc;
- struct resource *res;
- struct mfd_cell *cell = NULL;
- dma_addr_t fifo_base;
- int ret;
-
- davinci_vc = devm_kzalloc(&pdev->dev,
- sizeof(struct davinci_vc), GFP_KERNEL);
- if (!davinci_vc)
- return -ENOMEM;
-
- davinci_vc->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(davinci_vc->clk)) {
- dev_dbg(&pdev->dev,
- "could not get the clock for voice codec\n");
- return -ENODEV;
- }
- clk_enable(davinci_vc->clk);
-
- davinci_vc->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(davinci_vc->base)) {
- ret = PTR_ERR(davinci_vc->base);
- goto fail;
- }
- fifo_base = (dma_addr_t)res->start;
-
- davinci_vc->regmap = devm_regmap_init_mmio(&pdev->dev,
- davinci_vc->base,
- &davinci_vc_regmap);
- if (IS_ERR(davinci_vc->regmap)) {
- ret = PTR_ERR(davinci_vc->regmap);
- goto fail;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(&pdev->dev, "no DMA resource\n");
- ret = -ENXIO;
- goto fail;
- }
-
- davinci_vc->davinci_vcif.dma_tx_channel = res->start;
- davinci_vc->davinci_vcif.dma_tx_addr = fifo_base + DAVINCI_VC_WFIFO;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res) {
- dev_err(&pdev->dev, "no DMA resource\n");
- ret = -ENXIO;
- goto fail;
- }
-
- davinci_vc->davinci_vcif.dma_rx_channel = res->start;
- davinci_vc->davinci_vcif.dma_rx_addr = fifo_base + DAVINCI_VC_RFIFO;
-
- davinci_vc->dev = &pdev->dev;
- davinci_vc->pdev = pdev;
-
- /* Voice codec interface client */
- cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL];
- cell->name = "davinci-vcif";
- cell->platform_data = davinci_vc;
- cell->pdata_size = sizeof(*davinci_vc);
-
- /* Voice codec CQ93VC client */
- cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL];
- cell->name = "cq93vc-codec";
- cell->platform_data = davinci_vc;
- cell->pdata_size = sizeof(*davinci_vc);
-
- ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells,
- DAVINCI_VC_CELLS, NULL, 0, NULL);
- if (ret != 0) {
- dev_err(&pdev->dev, "fail to register client devices\n");
- goto fail;
- }
-
- return 0;
-
-fail:
- clk_disable(davinci_vc->clk);
-
- return ret;
-}
-
-static int davinci_vc_remove(struct platform_device *pdev)
-{
- struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
-
- mfd_remove_devices(&pdev->dev);
-
- clk_disable(davinci_vc->clk);
-
- return 0;
-}
-
-static struct platform_driver davinci_vc_driver = {
- .driver = {
- .name = "davinci_voicecodec",
- },
- .remove = davinci_vc_remove,
-};
-
-module_platform_driver_probe(davinci_vc_driver, davinci_vc_probe);
-
-MODULE_AUTHOR("Miguel Aguilar");
-MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
deleted file mode 100644
index 759c59690680..000000000000
--- a/drivers/mfd/dm355evm_msp.c
+++ /dev/null
@@ -1,454 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * dm355evm_msp.c - driver for MSP430 firmware on DM355EVM board
- *
- * Copyright (C) 2008 David Brownell
- */
-
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/gpio/machine.h>
-#include <linux/leds.h>
-#include <linux/i2c.h>
-#include <linux/mfd/dm355evm_msp.h>
-
-
-/*
- * The DM355 is a DaVinci chip with video support but no C64+ DSP. Its
- * EVM board has an MSP430 programmed with firmware for various board
- * support functions. This driver exposes some of them directly, and
- * supports other drivers (e.g. RTC, input) for more complex access.
- *
- * Because this firmware is entirely board-specific, this file embeds
- * knowledge that would be passed as platform_data in a generic driver.
- *
- * This driver was tested with firmware revision A4.
- */
-
-#if IS_ENABLED(CONFIG_INPUT_DM355EVM)
-#define msp_has_keyboard() true
-#else
-#define msp_has_keyboard() false
-#endif
-
-#if IS_ENABLED(CONFIG_LEDS_GPIO)
-#define msp_has_leds() true
-#else
-#define msp_has_leds() false
-#endif
-
-#if IS_ENABLED(CONFIG_RTC_DRV_DM355EVM)
-#define msp_has_rtc() true
-#else
-#define msp_has_rtc() false
-#endif
-
-#if IS_ENABLED(CONFIG_VIDEO_TVP514X)
-#define msp_has_tvp() true
-#else
-#define msp_has_tvp() false
-#endif
-
-
-/*----------------------------------------------------------------------*/
-
-/* REVISIT for paranoia's sake, retry reads/writes on error */
-
-static struct i2c_client *msp430;
-
-/**
- * dm355evm_msp_write - Writes a register in dm355evm_msp
- * @value: the value to be written
- * @reg: register address
- *
- * Returns result of operation - 0 is success, else negative errno
- */
-int dm355evm_msp_write(u8 value, u8 reg)
-{
- return i2c_smbus_write_byte_data(msp430, reg, value);
-}
-EXPORT_SYMBOL(dm355evm_msp_write);
-
-/**
- * dm355evm_msp_read - Reads a register from dm355evm_msp
- * @reg: register address
- *
- * Returns result of operation - value, or negative errno
- */
-int dm355evm_msp_read(u8 reg)
-{
- return i2c_smbus_read_byte_data(msp430, reg);
-}
-EXPORT_SYMBOL(dm355evm_msp_read);
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Many of the msp430 pins are just used as fixed-direction GPIOs.
- * We could export a few more of them this way, if we wanted.
- */
-#define MSP_GPIO(bit, reg) ((DM355EVM_MSP_ ## reg) << 3 | (bit))
-
-static const u8 msp_gpios[] = {
- /* eight leds */
- MSP_GPIO(0, LED), MSP_GPIO(1, LED),
- MSP_GPIO(2, LED), MSP_GPIO(3, LED),
- MSP_GPIO(4, LED), MSP_GPIO(5, LED),
- MSP_GPIO(6, LED), MSP_GPIO(7, LED),
- /* SW6 and the NTSC/nPAL jumper */
- MSP_GPIO(0, SWITCH1), MSP_GPIO(1, SWITCH1),
- MSP_GPIO(2, SWITCH1), MSP_GPIO(3, SWITCH1),
- MSP_GPIO(4, SWITCH1),
- /* switches on MMC/SD sockets */
- /*
- * Note: EVMDM355_ECP_VA4.pdf suggests that Bit 2 and 4 should be
- * checked for card detection. However on the EVM bit 1 and 3 gives
- * this status, for 0 and 1 instance respectively. The pdf also
- * suggests that Bit 1 and 3 should be checked for write protection.
- * However on the EVM bit 2 and 4 gives this status,for 0 and 1
- * instance respectively.
- */
- MSP_GPIO(2, SDMMC), MSP_GPIO(1, SDMMC), /* mmc0 WP, nCD */
- MSP_GPIO(4, SDMMC), MSP_GPIO(3, SDMMC), /* mmc1 WP, nCD */
-};
-
-static struct gpio_led evm_leds[] = {
- { .name = "dm355evm::ds14",
- .default_trigger = "heartbeat", },
- { .name = "dm355evm::ds15",
- .default_trigger = "mmc0", },
- { .name = "dm355evm::ds16",
- /* could also be a CE-ATA drive */
- .default_trigger = "mmc1", },
- { .name = "dm355evm::ds17",
- .default_trigger = "nand-disk", },
- { .name = "dm355evm::ds18", },
- { .name = "dm355evm::ds19", },
- { .name = "dm355evm::ds20", },
- { .name = "dm355evm::ds21", },
-};
-
-static struct gpio_led_platform_data evm_led_data = {
- .num_leds = ARRAY_SIZE(evm_leds),
- .leds = evm_leds,
-};
-
-static struct gpiod_lookup_table evm_leds_gpio_table = {
- .dev_id = "leds-gpio",
- .table = {
- /*
- * These GPIOs are on the dm355evm_msp
- * GPIO chip at index 0..7
- */
- GPIO_LOOKUP_IDX("dm355evm_msp", 0, NULL,
- 0, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("dm355evm_msp", 1, NULL,
- 1, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("dm355evm_msp", 2, NULL,
- 2, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("dm355evm_msp", 3, NULL,
- 3, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("dm355evm_msp", 4, NULL,
- 4, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("dm355evm_msp", 5, NULL,
- 5, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("dm355evm_msp", 6, NULL,
- 6, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("dm355evm_msp", 7, NULL,
- 7, GPIO_ACTIVE_LOW),
- { },
- },
-};
-
-#define MSP_GPIO_REG(offset) (msp_gpios[(offset)] >> 3)
-#define MSP_GPIO_MASK(offset) BIT(msp_gpios[(offset)] & 0x07)
-
-static int msp_gpio_in(struct gpio_chip *chip, unsigned offset)
-{
- switch (MSP_GPIO_REG(offset)) {
- case DM355EVM_MSP_SWITCH1:
- case DM355EVM_MSP_SWITCH2:
- case DM355EVM_MSP_SDMMC:
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static u8 msp_led_cache;
-
-static int msp_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- int reg, status;
-
- reg = MSP_GPIO_REG(offset);
- status = dm355evm_msp_read(reg);
- if (status < 0)
- return status;
- if (reg == DM355EVM_MSP_LED)
- msp_led_cache = status;
- return !!(status & MSP_GPIO_MASK(offset));
-}
-
-static int msp_gpio_out(struct gpio_chip *chip, unsigned offset, int value)
-{
- int mask, bits;
-
- /* NOTE: there are some other signals that could be
- * packaged as output GPIOs, but they aren't as useful
- * as the LEDs ... so for now we don't.
- */
- if (MSP_GPIO_REG(offset) != DM355EVM_MSP_LED)
- return -EINVAL;
-
- mask = MSP_GPIO_MASK(offset);
- bits = msp_led_cache;
-
- bits &= ~mask;
- if (value)
- bits |= mask;
- msp_led_cache = bits;
-
- return dm355evm_msp_write(bits, DM355EVM_MSP_LED);
-}
-
-static void msp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- msp_gpio_out(chip, offset, value);
-}
-
-static struct gpio_chip dm355evm_msp_gpio = {
- .label = "dm355evm_msp",
- .owner = THIS_MODULE,
- .direction_input = msp_gpio_in,
- .get = msp_gpio_get,
- .direction_output = msp_gpio_out,
- .set = msp_gpio_set,
- .base = -EINVAL, /* dynamic assignment */
- .ngpio = ARRAY_SIZE(msp_gpios),
- .can_sleep = true,
-};
-
-/*----------------------------------------------------------------------*/
-
-static struct device *add_child(struct i2c_client *client, const char *name,
- void *pdata, unsigned pdata_len,
- bool can_wakeup, int irq)
-{
- struct platform_device *pdev;
- int status;
-
- pdev = platform_device_alloc(name, -1);
- if (!pdev)
- return ERR_PTR(-ENOMEM);
-
- device_init_wakeup(&pdev->dev, can_wakeup);
- pdev->dev.parent = &client->dev;
-
- if (pdata) {
- status = platform_device_add_data(pdev, pdata, pdata_len);
- if (status < 0) {
- dev_dbg(&pdev->dev, "can't add platform_data\n");
- goto put_device;
- }
- }
-
- if (irq) {
- struct resource r = {
- .start = irq,
- .flags = IORESOURCE_IRQ,
- };
-
- status = platform_device_add_resources(pdev, &r, 1);
- if (status < 0) {
- dev_dbg(&pdev->dev, "can't add irq\n");
- goto put_device;
- }
- }
-
- status = platform_device_add(pdev);
- if (status)
- goto put_device;
-
- return &pdev->dev;
-
-put_device:
- platform_device_put(pdev);
- dev_err(&client->dev, "failed to add device %s\n", name);
- return ERR_PTR(status);
-}
-
-static int add_children(struct i2c_client *client)
-{
- static const struct {
- int offset;
- char *label;
- } config_inputs[] = {
- /* 8 == right after the LEDs */
- { 8 + 0, "sw6_1", },
- { 8 + 1, "sw6_2", },
- { 8 + 2, "sw6_3", },
- { 8 + 3, "sw6_4", },
- { 8 + 4, "NTSC/nPAL", },
- };
-
- struct device *child;
- int status;
- int i;
-
- /* GPIO-ish stuff */
- dm355evm_msp_gpio.parent = &client->dev;
- status = gpiochip_add_data(&dm355evm_msp_gpio, NULL);
- if (status < 0)
- return status;
-
- /* LED output */
- if (msp_has_leds()) {
- gpiod_add_lookup_table(&evm_leds_gpio_table);
- /* NOTE: these are the only fully programmable LEDs
- * on the board, since GPIO-61/ds22 (and many signals
- * going to DC7) must be used for AEMIF address lines
- * unless the top 1 GB of NAND is unused...
- */
- child = add_child(client, "leds-gpio",
- &evm_led_data, sizeof(evm_led_data),
- false, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- /* configuration inputs */
- for (i = 0; i < ARRAY_SIZE(config_inputs); i++) {
- int gpio = dm355evm_msp_gpio.base + config_inputs[i].offset;
-
- gpio_request_one(gpio, GPIOF_IN, config_inputs[i].label);
-
- /* make it easy for userspace to see these */
- gpio_export(gpio, false);
- }
-
- /* MMC/SD inputs -- right after the last config input */
- if (dev_get_platdata(&client->dev)) {
- void (*mmcsd_setup)(unsigned) = dev_get_platdata(&client->dev);
-
- mmcsd_setup(dm355evm_msp_gpio.base + 8 + 5);
- }
-
- /* RTC is a 32 bit counter, no alarm */
- if (msp_has_rtc()) {
- child = add_child(client, "rtc-dm355evm",
- NULL, 0, false, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- /* input from buttons and IR remote (uses the IRQ) */
- if (msp_has_keyboard()) {
- child = add_child(client, "dm355evm_keys",
- NULL, 0, true, client->irq);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- return 0;
-}
-
-/*----------------------------------------------------------------------*/
-
-static void dm355evm_command(unsigned command)
-{
- int status;
-
- status = dm355evm_msp_write(command, DM355EVM_MSP_COMMAND);
- if (status < 0)
- dev_err(&msp430->dev, "command %d failure %d\n",
- command, status);
-}
-
-static void dm355evm_power_off(void)
-{
- dm355evm_command(MSP_COMMAND_POWEROFF);
-}
-
-static void dm355evm_msp_remove(struct i2c_client *client)
-{
- pm_power_off = NULL;
- msp430 = NULL;
-}
-
-static int
-dm355evm_msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- int status;
- const char *video = msp_has_tvp() ? "TVP5146" : "imager";
-
- if (msp430)
- return -EBUSY;
- msp430 = client;
-
- /* display revision status; doubles as sanity check */
- status = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
- if (status < 0)
- goto fail;
- dev_info(&client->dev, "firmware v.%02X, %s as video-in\n",
- status, video);
-
- /* mux video input: either tvp5146 or some external imager */
- status = dm355evm_msp_write(msp_has_tvp() ? 0 : MSP_VIDEO_IMAGER,
- DM355EVM_MSP_VIDEO_IN);
- if (status < 0)
- dev_warn(&client->dev, "error %d muxing %s as video-in\n",
- status, video);
-
- /* init LED cache, and turn off the LEDs */
- msp_led_cache = 0xff;
- dm355evm_msp_write(msp_led_cache, DM355EVM_MSP_LED);
-
- /* export capabilities we support */
- status = add_children(client);
- if (status < 0)
- goto fail;
-
- /* PM hookup */
- pm_power_off = dm355evm_power_off;
-
- return 0;
-
-fail:
- /* FIXME remove children ... */
- dm355evm_msp_remove(client);
- return status;
-}
-
-static const struct i2c_device_id dm355evm_msp_ids[] = {
- { "dm355evm_msp", 0 },
- { /* end of list */ },
-};
-MODULE_DEVICE_TABLE(i2c, dm355evm_msp_ids);
-
-static struct i2c_driver dm355evm_msp_driver = {
- .driver.name = "dm355evm_msp",
- .id_table = dm355evm_msp_ids,
- .probe = dm355evm_msp_probe,
- .remove = dm355evm_msp_remove,
-};
-
-static int __init dm355evm_msp_init(void)
-{
- return i2c_add_driver(&dm355evm_msp_driver);
-}
-subsys_initcall(dm355evm_msp_init);
-
-static void __exit dm355evm_msp_exit(void)
-{
- i2c_del_driver(&dm355evm_msp_driver);
-}
-module_exit(dm355evm_msp_exit);
-
-MODULE_DESCRIPTION("Interface to MSP430 firmware on DM355EVM");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c
index 823595bcc9b7..089c2ce615b6 100644
--- a/drivers/mfd/fsl-imx25-tsadc.c
+++ b/drivers/mfd/fsl-imx25-tsadc.c
@@ -137,7 +137,6 @@ static int mx25_tsadc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mx25_tsadc *tsadc;
- struct resource *res;
int ret;
void __iomem *iomem;
@@ -145,8 +144,7 @@ static int mx25_tsadc_probe(struct platform_device *pdev)
if (!tsadc)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- iomem = devm_ioremap_resource(dev, res);
+ iomem = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
if (IS_ERR(iomem))
return PTR_ERR(iomem);
diff --git a/drivers/mfd/gateworks-gsc.c b/drivers/mfd/gateworks-gsc.c
index 9d7d870c44a8..c954ed265de8 100644
--- a/drivers/mfd/gateworks-gsc.c
+++ b/drivers/mfd/gateworks-gsc.c
@@ -189,8 +189,7 @@ static const struct regmap_irq_chip gsc_irq_chip = {
.num_irqs = ARRAY_SIZE(gsc_irqs),
.num_regs = 1,
.status_base = GSC_IRQ_STATUS,
- .mask_base = GSC_IRQ_ENABLE,
- .mask_invert = true,
+ .unmask_base = GSC_IRQ_ENABLE,
.ack_base = GSC_IRQ_STATUS,
.ack_invert = true,
};
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c
deleted file mode 100644
index b45b1346ab54..000000000000
--- a/drivers/mfd/htc-i2cpld.c
+++ /dev/null
@@ -1,627 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * htc-i2cpld.c
- * Chip driver for an unknown CPLD chip found on omap850 HTC devices like
- * the HTC Wizard and HTC Herald.
- * The cpld is located on the i2c bus and acts as an input/output GPIO
- * extender.
- *
- * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
- *
- * Based on work done in the linwizard project
- * Copyright (C) 2008-2009 Angelo Arrifano <miknix@gmail.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <linux/spinlock.h>
-#include <linux/htcpld.h>
-#include <linux/gpio/driver.h>
-#include <linux/gpio/machine.h>
-#include <linux/gpio/consumer.h>
-#include <linux/slab.h>
-
-struct htcpld_chip {
- spinlock_t lock;
-
- /* chip info */
- u8 reset;
- u8 addr;
- struct device *dev;
- struct i2c_client *client;
-
- /* Output details */
- u8 cache_out;
- struct gpio_chip chip_out;
-
- /* Input details */
- u8 cache_in;
- struct gpio_chip chip_in;
-
- u16 irqs_enabled;
- uint irq_start;
- int nirqs;
-
- unsigned int flow_type;
- /*
- * Work structure to allow for setting values outside of any
- * possible interrupt context
- */
- struct work_struct set_val_work;
-};
-
-struct htcpld_data {
- /* irq info */
- u16 irqs_enabled;
- uint irq_start;
- int nirqs;
- uint chained_irq;
- struct gpio_desc *int_reset_gpio_hi;
- struct gpio_desc *int_reset_gpio_lo;
-
- /* htcpld info */
- struct htcpld_chip *chip;
- unsigned int nchips;
-};
-
-/* There does not appear to be a way to proactively mask interrupts
- * on the htcpld chip itself. So, we simply ignore interrupts that
- * aren't desired. */
-static void htcpld_mask(struct irq_data *data)
-{
- struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
- chip->irqs_enabled &= ~(1 << (data->irq - chip->irq_start));
- pr_debug("HTCPLD mask %d %04x\n", data->irq, chip->irqs_enabled);
-}
-static void htcpld_unmask(struct irq_data *data)
-{
- struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
- chip->irqs_enabled |= 1 << (data->irq - chip->irq_start);
- pr_debug("HTCPLD unmask %d %04x\n", data->irq, chip->irqs_enabled);
-}
-
-static int htcpld_set_type(struct irq_data *data, unsigned int flags)
-{
- struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
-
- if (flags & ~IRQ_TYPE_SENSE_MASK)
- return -EINVAL;
-
- /* We only allow edge triggering */
- if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))
- return -EINVAL;
-
- chip->flow_type = flags;
- return 0;
-}
-
-static struct irq_chip htcpld_muxed_chip = {
- .name = "htcpld",
- .irq_mask = htcpld_mask,
- .irq_unmask = htcpld_unmask,
- .irq_set_type = htcpld_set_type,
-};
-
-/* To properly dispatch IRQ events, we need to read from the
- * chip. This is an I2C action that could possibly sleep
- * (which is bad in interrupt context) -- so we use a threaded
- * interrupt handler to get around that.
- */
-static irqreturn_t htcpld_handler(int irq, void *dev)
-{
- struct htcpld_data *htcpld = dev;
- unsigned int i;
- unsigned long flags;
- int irqpin;
-
- if (!htcpld) {
- pr_debug("htcpld is null in ISR\n");
- return IRQ_HANDLED;
- }
-
- /*
- * For each chip, do a read of the chip and trigger any interrupts
- * desired. The interrupts will be triggered from LSB to MSB (i.e.
- * bit 0 first, then bit 1, etc.)
- *
- * For chips that have no interrupt range specified, just skip 'em.
- */
- for (i = 0; i < htcpld->nchips; i++) {
- struct htcpld_chip *chip = &htcpld->chip[i];
- struct i2c_client *client;
- int val;
- unsigned long uval, old_val;
-
- if (!chip) {
- pr_debug("chip %d is null in ISR\n", i);
- continue;
- }
-
- if (chip->nirqs == 0)
- continue;
-
- client = chip->client;
- if (!client) {
- pr_debug("client %d is null in ISR\n", i);
- continue;
- }
-
- /* Scan the chip */
- val = i2c_smbus_read_byte_data(client, chip->cache_out);
- if (val < 0) {
- /* Throw a warning and skip this chip */
- dev_warn(chip->dev, "Unable to read from chip: %d\n",
- val);
- continue;
- }
-
- uval = (unsigned long)val;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- /* Save away the old value so we can compare it */
- old_val = chip->cache_in;
-
- /* Write the new value */
- chip->cache_in = uval;
-
- spin_unlock_irqrestore(&chip->lock, flags);
-
- /*
- * For each bit in the data (starting at bit 0), trigger
- * associated interrupts.
- */
- for (irqpin = 0; irqpin < chip->nirqs; irqpin++) {
- unsigned oldb, newb, type = chip->flow_type;
-
- irq = chip->irq_start + irqpin;
-
- /* Run the IRQ handler, but only if the bit value
- * changed, and the proper flags are set */
- oldb = (old_val >> irqpin) & 1;
- newb = (uval >> irqpin) & 1;
-
- if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) ||
- (oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) {
- pr_debug("fire IRQ %d\n", irqpin);
- generic_handle_irq(irq);
- }
- }
- }
-
- /*
- * In order to continue receiving interrupts, the int_reset_gpio must
- * be asserted.
- */
- if (htcpld->int_reset_gpio_hi)
- gpiod_set_value(htcpld->int_reset_gpio_hi, 1);
- if (htcpld->int_reset_gpio_lo)
- gpiod_set_value(htcpld->int_reset_gpio_lo, 0);
-
- return IRQ_HANDLED;
-}
-
-/*
- * The GPIO set routines can be called from interrupt context, especially if,
- * for example they're attached to the led-gpio framework and a trigger is
- * enabled. As such, we declared work above in the htcpld_chip structure,
- * and that work is scheduled in the set routine. The kernel can then run
- * the I2C functions, which will sleep, in process context.
- */
-static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val)
-{
- struct i2c_client *client;
- struct htcpld_chip *chip_data = gpiochip_get_data(chip);
- unsigned long flags;
-
- client = chip_data->client;
- if (!client)
- return;
-
- spin_lock_irqsave(&chip_data->lock, flags);
- if (val)
- chip_data->cache_out |= (1 << offset);
- else
- chip_data->cache_out &= ~(1 << offset);
- spin_unlock_irqrestore(&chip_data->lock, flags);
-
- schedule_work(&(chip_data->set_val_work));
-}
-
-static void htcpld_chip_set_ni(struct work_struct *work)
-{
- struct htcpld_chip *chip_data;
- struct i2c_client *client;
-
- chip_data = container_of(work, struct htcpld_chip, set_val_work);
- client = chip_data->client;
- i2c_smbus_read_byte_data(client, chip_data->cache_out);
-}
-
-static int htcpld_chip_get(struct gpio_chip *chip, unsigned offset)
-{
- struct htcpld_chip *chip_data = gpiochip_get_data(chip);
- u8 cache;
-
- if (!strncmp(chip->label, "htcpld-out", 10)) {
- cache = chip_data->cache_out;
- } else if (!strncmp(chip->label, "htcpld-in", 9)) {
- cache = chip_data->cache_in;
- } else
- return -EINVAL;
-
- return (cache >> offset) & 1;
-}
-
-static int htcpld_direction_output(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- htcpld_chip_set(chip, offset, value);
- return 0;
-}
-
-static int htcpld_direction_input(struct gpio_chip *chip,
- unsigned offset)
-{
- /*
- * No-op: this function can only be called on the input chip.
- * We do however make sure the offset is within range.
- */
- return (offset < chip->ngpio) ? 0 : -EINVAL;
-}
-
-static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct htcpld_chip *chip_data = gpiochip_get_data(chip);
-
- if (offset < chip_data->nirqs)
- return chip_data->irq_start + offset;
- else
- return -EINVAL;
-}
-
-static void htcpld_chip_reset(struct i2c_client *client)
-{
- struct htcpld_chip *chip_data = i2c_get_clientdata(client);
- if (!chip_data)
- return;
-
- i2c_smbus_read_byte_data(
- client, (chip_data->cache_out = chip_data->reset));
-}
-
-static int htcpld_setup_chip_irq(
- struct platform_device *pdev,
- int chip_index)
-{
- struct htcpld_data *htcpld;
- struct htcpld_chip *chip;
- unsigned int irq, irq_end;
-
- /* Get the platform and driver data */
- htcpld = platform_get_drvdata(pdev);
- chip = &htcpld->chip[chip_index];
-
- /* Setup irq handlers */
- irq_end = chip->irq_start + chip->nirqs;
- for (irq = chip->irq_start; irq < irq_end; irq++) {
- irq_set_chip_and_handler(irq, &htcpld_muxed_chip,
- handle_simple_irq);
- irq_set_chip_data(irq, chip);
- irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
- }
-
- return 0;
-}
-
-static int htcpld_register_chip_i2c(
- struct platform_device *pdev,
- int chip_index)
-{
- struct htcpld_data *htcpld;
- struct device *dev = &pdev->dev;
- struct htcpld_core_platform_data *pdata;
- struct htcpld_chip *chip;
- struct htcpld_chip_platform_data *plat_chip_data;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
- struct i2c_board_info info;
-
- /* Get the platform and driver data */
- pdata = dev_get_platdata(dev);
- htcpld = platform_get_drvdata(pdev);
- chip = &htcpld->chip[chip_index];
- plat_chip_data = &pdata->chip[chip_index];
-
- adapter = i2c_get_adapter(pdata->i2c_adapter_id);
- if (!adapter) {
- /* Eek, no such I2C adapter! Bail out. */
- dev_warn(dev, "Chip at i2c address 0x%x: Invalid i2c adapter %d\n",
- plat_chip_data->addr, pdata->i2c_adapter_id);
- return -ENODEV;
- }
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
- dev_warn(dev, "i2c adapter %d non-functional\n",
- pdata->i2c_adapter_id);
- i2c_put_adapter(adapter);
- return -EINVAL;
- }
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = plat_chip_data->addr;
- strscpy(info.type, "htcpld-chip", I2C_NAME_SIZE);
- info.platform_data = chip;
-
- /* Add the I2C device. This calls the probe() function. */
- client = i2c_new_client_device(adapter, &info);
- if (IS_ERR(client)) {
- /* I2C device registration failed, contineu with the next */
- dev_warn(dev, "Unable to add I2C device for 0x%x\n",
- plat_chip_data->addr);
- i2c_put_adapter(adapter);
- return PTR_ERR(client);
- }
-
- i2c_set_clientdata(client, chip);
- snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%x", client->addr);
- chip->client = client;
-
- /* Reset the chip */
- htcpld_chip_reset(client);
- chip->cache_in = i2c_smbus_read_byte_data(client, chip->cache_out);
-
- return 0;
-}
-
-static void htcpld_unregister_chip_i2c(
- struct platform_device *pdev,
- int chip_index)
-{
- struct htcpld_data *htcpld;
- struct htcpld_chip *chip;
-
- /* Get the platform and driver data */
- htcpld = platform_get_drvdata(pdev);
- chip = &htcpld->chip[chip_index];
-
- i2c_unregister_device(chip->client);
-}
-
-static int htcpld_register_chip_gpio(
- struct platform_device *pdev,
- int chip_index)
-{
- struct htcpld_data *htcpld;
- struct device *dev = &pdev->dev;
- struct htcpld_core_platform_data *pdata;
- struct htcpld_chip *chip;
- struct htcpld_chip_platform_data *plat_chip_data;
- struct gpio_chip *gpio_chip;
- int ret = 0;
-
- /* Get the platform and driver data */
- pdata = dev_get_platdata(dev);
- htcpld = platform_get_drvdata(pdev);
- chip = &htcpld->chip[chip_index];
- plat_chip_data = &pdata->chip[chip_index];
-
- /* Setup the GPIO chips */
- gpio_chip = &(chip->chip_out);
- gpio_chip->label = "htcpld-out";
- gpio_chip->parent = dev;
- gpio_chip->owner = THIS_MODULE;
- gpio_chip->get = htcpld_chip_get;
- gpio_chip->set = htcpld_chip_set;
- gpio_chip->direction_input = NULL;
- gpio_chip->direction_output = htcpld_direction_output;
- gpio_chip->base = plat_chip_data->gpio_out_base;
- gpio_chip->ngpio = plat_chip_data->num_gpios;
-
- gpio_chip = &(chip->chip_in);
- gpio_chip->label = "htcpld-in";
- gpio_chip->parent = dev;
- gpio_chip->owner = THIS_MODULE;
- gpio_chip->get = htcpld_chip_get;
- gpio_chip->set = NULL;
- gpio_chip->direction_input = htcpld_direction_input;
- gpio_chip->direction_output = NULL;
- gpio_chip->to_irq = htcpld_chip_to_irq;
- gpio_chip->base = plat_chip_data->gpio_in_base;
- gpio_chip->ngpio = plat_chip_data->num_gpios;
-
- /* Add the GPIO chips */
- ret = gpiochip_add_data(&(chip->chip_out), chip);
- if (ret) {
- dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n",
- plat_chip_data->addr, ret);
- return ret;
- }
-
- ret = gpiochip_add_data(&(chip->chip_in), chip);
- if (ret) {
- dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n",
- plat_chip_data->addr, ret);
- gpiochip_remove(&(chip->chip_out));
- return ret;
- }
-
- return 0;
-}
-
-static int htcpld_setup_chips(struct platform_device *pdev)
-{
- struct htcpld_data *htcpld;
- struct device *dev = &pdev->dev;
- struct htcpld_core_platform_data *pdata;
- int i;
-
- /* Get the platform and driver data */
- pdata = dev_get_platdata(dev);
- htcpld = platform_get_drvdata(pdev);
-
- /* Setup each chip's output GPIOs */
- htcpld->nchips = pdata->num_chip;
- htcpld->chip = devm_kcalloc(dev,
- htcpld->nchips,
- sizeof(struct htcpld_chip),
- GFP_KERNEL);
- if (!htcpld->chip)
- return -ENOMEM;
-
- /* Add the chips as best we can */
- for (i = 0; i < htcpld->nchips; i++) {
- int ret;
-
- /* Setup the HTCPLD chips */
- htcpld->chip[i].reset = pdata->chip[i].reset;
- htcpld->chip[i].cache_out = pdata->chip[i].reset;
- htcpld->chip[i].cache_in = 0;
- htcpld->chip[i].dev = dev;
- htcpld->chip[i].irq_start = pdata->chip[i].irq_base;
- htcpld->chip[i].nirqs = pdata->chip[i].num_irqs;
-
- INIT_WORK(&(htcpld->chip[i].set_val_work), &htcpld_chip_set_ni);
- spin_lock_init(&(htcpld->chip[i].lock));
-
- /* Setup the interrupts for the chip */
- if (htcpld->chained_irq) {
- ret = htcpld_setup_chip_irq(pdev, i);
- if (ret)
- continue;
- }
-
- /* Register the chip with I2C */
- ret = htcpld_register_chip_i2c(pdev, i);
- if (ret)
- continue;
-
-
- /* Register the chips with the GPIO subsystem */
- ret = htcpld_register_chip_gpio(pdev, i);
- if (ret) {
- /* Unregister the chip from i2c and continue */
- htcpld_unregister_chip_i2c(pdev, i);
- continue;
- }
-
- dev_info(dev, "Registered chip at 0x%x\n", pdata->chip[i].addr);
- }
-
- return 0;
-}
-
-static int htcpld_core_probe(struct platform_device *pdev)
-{
- struct htcpld_data *htcpld;
- struct device *dev = &pdev->dev;
- struct htcpld_core_platform_data *pdata;
- struct resource *res;
- int ret = 0;
-
- if (!dev)
- return -ENODEV;
-
- pdata = dev_get_platdata(dev);
- if (!pdata) {
- dev_warn(dev, "Platform data not found for htcpld core!\n");
- return -ENXIO;
- }
-
- htcpld = devm_kzalloc(dev, sizeof(struct htcpld_data), GFP_KERNEL);
- if (!htcpld)
- return -ENOMEM;
-
- /* Find chained irq */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res) {
- int flags;
- htcpld->chained_irq = res->start;
-
- /* Setup the chained interrupt handler */
- flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
- IRQF_ONESHOT;
- ret = request_threaded_irq(htcpld->chained_irq,
- NULL, htcpld_handler,
- flags, pdev->name, htcpld);
- if (ret) {
- dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret);
- return ret;
- } else
- device_init_wakeup(dev, 0);
- }
-
- /* Set the driver data */
- platform_set_drvdata(pdev, htcpld);
-
- /* Setup the htcpld chips */
- ret = htcpld_setup_chips(pdev);
- if (ret)
- return ret;
-
- /* Request the GPIO(s) for the int reset and set them up */
- htcpld->int_reset_gpio_hi = gpiochip_request_own_desc(&htcpld->chip[2].chip_out,
- 7, "htcpld-core", GPIO_ACTIVE_HIGH,
- GPIOD_OUT_HIGH);
- if (IS_ERR(htcpld->int_reset_gpio_hi)) {
- /*
- * If it failed, that sucks, but we can probably
- * continue on without it.
- */
- htcpld->int_reset_gpio_hi = NULL;
- dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n");
- }
-
- htcpld->int_reset_gpio_lo = gpiochip_request_own_desc(&htcpld->chip[2].chip_out,
- 0, "htcpld-core", GPIO_ACTIVE_HIGH,
- GPIOD_OUT_LOW);
- if (IS_ERR(htcpld->int_reset_gpio_lo)) {
- /*
- * If it failed, that sucks, but we can probably
- * continue on without it.
- */
- htcpld->int_reset_gpio_lo = NULL;
- dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n");
- }
-
- dev_info(dev, "Initialized successfully\n");
- return 0;
-}
-
-/* The I2C Driver -- used internally */
-static const struct i2c_device_id htcpld_chip_id[] = {
- { "htcpld-chip", 0 },
- { }
-};
-
-static struct i2c_driver htcpld_chip_driver = {
- .driver = {
- .name = "htcpld-chip",
- },
- .id_table = htcpld_chip_id,
-};
-
-/* The Core Driver */
-static struct platform_driver htcpld_core_driver = {
- .driver = {
- .name = "i2c-htcpld",
- },
-};
-
-static int __init htcpld_core_init(void)
-{
- int ret;
-
- /* Register the I2C Chip driver */
- ret = i2c_add_driver(&htcpld_chip_driver);
- if (ret)
- return ret;
-
- /* Probe for our chips */
- return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe);
-}
-device_initcall(htcpld_core_init);
diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c
index f3d418810693..7338cc16f327 100644
--- a/drivers/mfd/khadas-mcu.c
+++ b/drivers/mfd/khadas-mcu.c
@@ -84,8 +84,7 @@ static struct mfd_cell khadas_mcu_cells[] = {
{ .name = "khadas-mcu-user-mem", },
};
-static int khadas_mcu_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int khadas_mcu_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct khadas_mcu *ddata;
@@ -135,7 +134,7 @@ static struct i2c_driver khadas_mcu_driver = {
.name = "khadas-mcu-core",
.of_match_table = of_match_ptr(khadas_mcu_of_match),
},
- .probe = khadas_mcu_probe,
+ .probe_new = khadas_mcu_probe,
};
module_i2c_driver(khadas_mcu_driver);
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c
index be32ffc5af38..74a553329416 100644
--- a/drivers/mfd/lm3533-core.c
+++ b/drivers/mfd/lm3533-core.c
@@ -584,8 +584,7 @@ static const struct regmap_config regmap_config = {
.precious_reg = lm3533_precious_register,
};
-static int lm3533_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int lm3533_i2c_probe(struct i2c_client *i2c)
{
struct lm3533 *lm3533;
@@ -627,7 +626,7 @@ static struct i2c_driver lm3533_i2c_driver = {
.name = "lm3533",
},
.id_table = lm3533_i2c_ids,
- .probe = lm3533_i2c_probe,
+ .probe_new = lm3533_i2c_probe,
.remove = lm3533_i2c_remove,
};
diff --git a/drivers/mfd/lp3943.c b/drivers/mfd/lp3943.c
index 13cb89be3d66..f9f39b53d030 100644
--- a/drivers/mfd/lp3943.c
+++ b/drivers/mfd/lp3943.c
@@ -102,7 +102,7 @@ static const struct regmap_config lp3943_regmap_config = {
.max_register = LP3943_MAX_REGISTERS,
};
-static int lp3943_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+static int lp3943_probe(struct i2c_client *cl)
{
struct lp3943 *lp3943;
struct device *dev = &cl->dev;
@@ -140,7 +140,7 @@ MODULE_DEVICE_TABLE(of, lp3943_of_match);
#endif
static struct i2c_driver lp3943_driver = {
- .probe = lp3943_probe,
+ .probe_new = lp3943_probe,
.driver = {
.name = "lp3943",
.of_match_table = of_match_ptr(lp3943_of_match),
diff --git a/drivers/mfd/lp873x.c b/drivers/mfd/lp873x.c
index b6166dec492d..c81c5c9ad748 100644
--- a/drivers/mfd/lp873x.c
+++ b/drivers/mfd/lp873x.c
@@ -24,8 +24,7 @@ static const struct mfd_cell lp873x_cells[] = {
{ .name = "lp873x-gpio", },
};
-static int lp873x_probe(struct i2c_client *client,
- const struct i2c_device_id *ids)
+static int lp873x_probe(struct i2c_client *client)
{
struct lp873x *lp873;
int ret;
@@ -79,7 +78,7 @@ static struct i2c_driver lp873x_driver = {
.name = "lp873x",
.of_match_table = of_lp873x_match_table,
},
- .probe = lp873x_probe,
+ .probe_new = lp873x_probe,
.id_table = lp873x_id_table,
};
module_i2c_driver(lp873x_driver);
diff --git a/drivers/mfd/lp87565.c b/drivers/mfd/lp87565.c
index a52ab76febb3..568f0f01ea0d 100644
--- a/drivers/mfd/lp87565.c
+++ b/drivers/mfd/lp87565.c
@@ -43,8 +43,7 @@ static const struct of_device_id of_lp87565_match_table[] = {
};
MODULE_DEVICE_TABLE(of, of_lp87565_match_table);
-static int lp87565_probe(struct i2c_client *client,
- const struct i2c_device_id *ids)
+static int lp87565_probe(struct i2c_client *client)
{
struct lp87565 *lp87565;
const struct of_device_id *of_id;
@@ -120,7 +119,7 @@ static struct i2c_driver lp87565_driver = {
.name = "lp87565",
.of_match_table = of_lp87565_match_table,
},
- .probe = lp87565_probe,
+ .probe_new = lp87565_probe,
.shutdown = lp87565_shutdown,
.id_table = lp87565_id_table,
};
diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
index 724a5712b36b..fe809b64147e 100644
--- a/drivers/mfd/lp8788.c
+++ b/drivers/mfd/lp8788.c
@@ -166,7 +166,7 @@ static const struct regmap_config lp8788_regmap_config = {
.max_register = MAX_LP8788_REGISTERS,
};
-static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+static int lp8788_probe(struct i2c_client *cl)
{
struct lp8788 *lp;
struct lp8788_platform_data *pdata = dev_get_platdata(&cl->dev);
@@ -225,7 +225,7 @@ static struct i2c_driver lp8788_driver = {
.driver = {
.name = "lp8788",
},
- .probe = lp8788_probe,
+ .probe_new = lp8788_probe,
.remove = lp8788_remove,
.id_table = lp8788_ids,
};
diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c
index a2abc0094def..bdbd5bfc9714 100644
--- a/drivers/mfd/madera-core.c
+++ b/drivers/mfd/madera-core.c
@@ -8,13 +8,12 @@
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
#include <linux/of.h>
-#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
diff --git a/drivers/mfd/madera-i2c.c b/drivers/mfd/madera-i2c.c
index 915d2f95bad3..47e65d88feb0 100644
--- a/drivers/mfd/madera-i2c.c
+++ b/drivers/mfd/madera-i2c.c
@@ -17,9 +17,9 @@
#include "madera.h"
-static int madera_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int madera_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct madera *madera;
const struct regmap_config *regmap_16bit_config = NULL;
const struct regmap_config *regmap_32bit_config = NULL;
@@ -139,7 +139,7 @@ static struct i2c_driver madera_i2c_driver = {
.pm = &madera_pm_ops,
.of_match_table = of_match_ptr(madera_of_match),
},
- .probe = madera_i2c_probe,
+ .probe_new = madera_i2c_probe,
.remove = madera_i2c_remove,
.id_table = madera_i2c_id,
};
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
index d44ad6f33742..0e3731e9e9b5 100644
--- a/drivers/mfd/max14577.c
+++ b/drivers/mfd/max14577.c
@@ -209,8 +209,7 @@ static const struct regmap_irq max14577_irqs[] = {
static const struct regmap_irq_chip max14577_irq_chip = {
.name = "max14577",
.status_base = MAX14577_REG_INT1,
- .mask_base = MAX14577_REG_INTMASK1,
- .mask_invert = true,
+ .unmask_base = MAX14577_REG_INTMASK1,
.num_regs = 3,
.irqs = max14577_irqs,
.num_irqs = ARRAY_SIZE(max14577_irqs),
@@ -239,8 +238,7 @@ static const struct regmap_irq max77836_muic_irqs[] = {
static const struct regmap_irq_chip max77836_muic_irq_chip = {
.name = "max77836-muic",
.status_base = MAX14577_REG_INT1,
- .mask_base = MAX14577_REG_INTMASK1,
- .mask_invert = true,
+ .unmask_base = MAX14577_REG_INTMASK1,
.num_regs = 3,
.irqs = max77836_muic_irqs,
.num_irqs = ARRAY_SIZE(max77836_muic_irqs),
@@ -255,7 +253,6 @@ static const struct regmap_irq_chip max77836_pmic_irq_chip = {
.name = "max77836-pmic",
.status_base = MAX77836_PMIC_REG_TOPSYS_INT,
.mask_base = MAX77836_PMIC_REG_TOPSYS_INT_MASK,
- .mask_invert = false,
.num_regs = 1,
.irqs = max77836_pmic_irqs,
.num_irqs = ARRAY_SIZE(max77836_pmic_irqs),
@@ -358,9 +355,9 @@ static void max77836_remove(struct max14577 *max14577)
i2c_unregister_device(max14577->i2c_pmic);
}
-static int max14577_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int max14577_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct max14577 *max14577;
struct max14577_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct device_node *np = i2c->dev.of_node;
@@ -480,7 +477,6 @@ static const struct i2c_device_id max14577_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, max14577_i2c_id);
-#ifdef CONFIG_PM_SLEEP
static int max14577_suspend(struct device *dev)
{
struct i2c_client *i2c = to_i2c_client(dev);
@@ -513,17 +509,16 @@ static int max14577_resume(struct device *dev)
return 0;
}
-#endif /* CONFIG_PM_SLEEP */
-static SIMPLE_DEV_PM_OPS(max14577_pm, max14577_suspend, max14577_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(max14577_pm, max14577_suspend, max14577_resume);
static struct i2c_driver max14577_i2c_driver = {
.driver = {
.name = "max14577",
- .pm = &max14577_pm,
+ .pm = pm_sleep_ptr(&max14577_pm),
.of_match_table = max14577_dt_match,
},
- .probe = max14577_i2c_probe,
+ .probe_new = max14577_i2c_probe,
.remove = max14577_i2c_remove,
.id_table = max14577_i2c_id,
};
diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c
index a6661e07035b..cbd2297126f0 100644
--- a/drivers/mfd/max77620.c
+++ b/drivers/mfd/max77620.c
@@ -494,9 +494,9 @@ static void max77620_pm_power_off(void)
MAX77620_ONOFFCNFG1_SFT_RST);
}
-static int max77620_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int max77620_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
const struct regmap_config *rmap_config;
struct max77620_chip *chip;
const struct mfd_cell *mfd_cells;
@@ -576,7 +576,6 @@ static int max77620_probe(struct i2c_client *client,
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int max77620_set_fps_period(struct max77620_chip *chip,
int fps_id, int time_period)
{
@@ -683,7 +682,6 @@ out:
return 0;
}
-#endif
static const struct i2c_device_id max77620_id[] = {
{"max77620", MAX77620},
@@ -692,16 +690,15 @@ static const struct i2c_device_id max77620_id[] = {
{},
};
-static const struct dev_pm_ops max77620_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume)
-};
+static DEFINE_SIMPLE_DEV_PM_OPS(max77620_pm_ops,
+ max77620_i2c_suspend, max77620_i2c_resume);
static struct i2c_driver max77620_driver = {
.driver = {
.name = "max77620",
- .pm = &max77620_pm_ops,
+ .pm = pm_sleep_ptr(&max77620_pm_ops),
},
- .probe = max77620_probe,
+ .probe_new = max77620_probe,
.id_table = max77620_id,
};
builtin_i2c_driver(max77620_driver);
diff --git a/drivers/mfd/max77650.c b/drivers/mfd/max77650.c
index 777485a33bc0..3c07fcdd9d07 100644
--- a/drivers/mfd/max77650.c
+++ b/drivers/mfd/max77650.c
@@ -138,7 +138,6 @@ static const struct regmap_irq_chip max77650_irq_chip = {
.status_base = MAX77650_REG_INT_GLBL,
.mask_base = MAX77650_REG_INTM_GLBL,
.type_in_mask = true,
- .type_invert = true,
.init_ack_masked = true,
.clear_on_unmask = true,
};
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
index 2ac64277fb84..f8e863f3fc95 100644
--- a/drivers/mfd/max77686.c
+++ b/drivers/mfd/max77686.c
@@ -226,7 +226,6 @@ static int max77686_i2c_probe(struct i2c_client *i2c)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int max77686_suspend(struct device *dev)
{
struct i2c_client *i2c = to_i2c_client(dev);
@@ -261,14 +260,13 @@ static int max77686_resume(struct device *dev)
return 0;
}
-#endif /* CONFIG_PM_SLEEP */
-static SIMPLE_DEV_PM_OPS(max77686_pm, max77686_suspend, max77686_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(max77686_pm, max77686_suspend, max77686_resume);
static struct i2c_driver max77686_i2c_driver = {
.driver = {
.name = "max77686",
- .pm = &max77686_pm,
+ .pm = pm_sleep_ptr(&max77686_pm),
.of_match_table = max77686_pmic_dt_match,
},
.probe_new = max77686_i2c_probe,
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
index 7088cb6f9174..3995e8769f49 100644
--- a/drivers/mfd/max77693.c
+++ b/drivers/mfd/max77693.c
@@ -66,7 +66,6 @@ static const struct regmap_irq_chip max77693_led_irq_chip = {
.name = "max77693-led",
.status_base = MAX77693_LED_REG_FLASH_INT,
.mask_base = MAX77693_LED_REG_FLASH_INT_MASK,
- .mask_invert = false,
.num_regs = 1,
.irqs = max77693_led_irqs,
.num_irqs = ARRAY_SIZE(max77693_led_irqs),
@@ -82,7 +81,6 @@ static const struct regmap_irq_chip max77693_topsys_irq_chip = {
.name = "max77693-topsys",
.status_base = MAX77693_PMIC_REG_TOPSYS_INT,
.mask_base = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
- .mask_invert = false,
.num_regs = 1,
.irqs = max77693_topsys_irqs,
.num_irqs = ARRAY_SIZE(max77693_topsys_irqs),
@@ -100,7 +98,6 @@ static const struct regmap_irq_chip max77693_charger_irq_chip = {
.name = "max77693-charger",
.status_base = MAX77693_CHG_REG_CHG_INT,
.mask_base = MAX77693_CHG_REG_CHG_INT_MASK,
- .mask_invert = false,
.num_regs = 1,
.irqs = max77693_charger_irqs,
.num_irqs = ARRAY_SIZE(max77693_charger_irqs),
@@ -136,8 +133,7 @@ static const struct regmap_irq max77693_muic_irqs[] = {
static const struct regmap_irq_chip max77693_muic_irq_chip = {
.name = "max77693-muic",
.status_base = MAX77693_MUIC_REG_INT1,
- .mask_base = MAX77693_MUIC_REG_INTMASK1,
- .mask_invert = true,
+ .unmask_base = MAX77693_MUIC_REG_INTMASK1,
.num_regs = 3,
.irqs = max77693_muic_irqs,
.num_irqs = ARRAY_SIZE(max77693_muic_irqs),
@@ -149,9 +145,9 @@ static const struct regmap_config max77693_regmap_haptic_config = {
.max_register = MAX77693_HAPTIC_REG_END,
};
-static int max77693_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int max77693_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct max77693_dev *max77693;
unsigned int reg_data;
int ret = 0;
@@ -360,7 +356,7 @@ static struct i2c_driver max77693_i2c_driver = {
.pm = &max77693_pm,
.of_match_table = of_match_ptr(max77693_dt_match),
},
- .probe = max77693_i2c_probe,
+ .probe_new = max77693_i2c_probe,
.remove = max77693_i2c_remove,
.id_table = max77693_i2c_id,
};
diff --git a/drivers/mfd/max77843.c b/drivers/mfd/max77843.c
index 209ee24d9ce1..8ff0723808c8 100644
--- a/drivers/mfd/max77843.c
+++ b/drivers/mfd/max77843.c
@@ -59,7 +59,6 @@ static const struct regmap_irq_chip max77843_irq_chip = {
.name = "max77843",
.status_base = MAX77843_SYS_REG_SYSINTSRC,
.mask_base = MAX77843_SYS_REG_SYSINTMASK,
- .mask_invert = false,
.num_regs = 1,
.irqs = max77843_irqs,
.num_irqs = ARRAY_SIZE(max77843_irqs),
@@ -93,9 +92,9 @@ err_chg_i2c:
return ret;
}
-static int max77843_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int max77843_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct max77693_dev *max77843;
unsigned int reg_data;
int ret;
@@ -208,7 +207,7 @@ static struct i2c_driver max77843_i2c_driver = {
.of_match_table = max77843_dt_match,
.suppress_bind_attrs = true,
},
- .probe = max77843_probe,
+ .probe_new = max77843_probe,
.id_table = max77843_id,
};
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
index c340080971ce..a69b865c6eac 100644
--- a/drivers/mfd/max8907.c
+++ b/drivers/mfd/max8907.c
@@ -181,8 +181,7 @@ static void max8907_power_off(void)
MAX8907_MASK_POWER_OFF, MAX8907_MASK_POWER_OFF);
}
-static int max8907_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int max8907_i2c_probe(struct i2c_client *i2c)
{
struct max8907 *max8907;
int ret;
@@ -314,7 +313,7 @@ static struct i2c_driver max8907_i2c_driver = {
.name = "max8907",
.of_match_table = of_match_ptr(max8907_of_match),
},
- .probe = max8907_i2c_probe,
+ .probe_new = max8907_i2c_probe,
.remove = max8907_i2c_remove,
.id_table = max8907_i2c_id,
};
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
index 04101da42bd3..4057fd15c29e 100644
--- a/drivers/mfd/max8925-i2c.c
+++ b/drivers/mfd/max8925-i2c.c
@@ -144,8 +144,7 @@ static int max8925_dt_init(struct device_node *np, struct device *dev,
return 0;
}
-static int max8925_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int max8925_probe(struct i2c_client *client)
{
struct max8925_platform_data *pdata = dev_get_platdata(&client->dev);
struct max8925_chip *chip;
@@ -207,7 +206,6 @@ static void max8925_remove(struct i2c_client *client)
i2c_unregister_device(chip->rtc);
}
-#ifdef CONFIG_PM_SLEEP
static int max8925_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -227,9 +225,9 @@ static int max8925_resume(struct device *dev)
disable_irq_wake(chip->core_irq);
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(max8925_pm_ops,
+ max8925_suspend, max8925_resume);
static const struct of_device_id max8925_dt_ids[] = {
{ .compatible = "maxim,max8925", },
@@ -239,10 +237,10 @@ static const struct of_device_id max8925_dt_ids[] = {
static struct i2c_driver max8925_driver = {
.driver = {
.name = "max8925",
- .pm = &max8925_pm_ops,
+ .pm = pm_sleep_ptr(&max8925_pm_ops),
.of_match_table = max8925_dt_ids,
},
- .probe = max8925_probe,
+ .probe_new = max8925_probe,
.remove = max8925_remove,
.id_table = max8925_id_table,
};
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index 2141de78115d..79d551b86150 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -152,9 +152,9 @@ static inline unsigned long max8997_i2c_get_driver_data(struct i2c_client *i2c,
return id->driver_data;
}
-static int max8997_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int max8997_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct max8997_dev *max8997;
struct max8997_platform_data *pdata = dev_get_platdata(&i2c->dev);
int ret = 0;
@@ -478,7 +478,7 @@ static struct i2c_driver max8997_i2c_driver = {
.suppress_bind_attrs = true,
.of_match_table = of_match_ptr(max8997_pmic_dt_match),
},
- .probe = max8997_i2c_probe,
+ .probe_new = max8997_i2c_probe,
.id_table = max8997_i2c_id,
};
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c
index 0eb15e611b67..122f7b931f5a 100644
--- a/drivers/mfd/max8998.c
+++ b/drivers/mfd/max8998.c
@@ -162,9 +162,9 @@ static inline unsigned long max8998_i2c_get_driver_data(struct i2c_client *i2c,
return id->driver_data;
}
-static int max8998_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int max8998_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct max8998_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct max8998_dev *max8998;
int ret = 0;
@@ -348,7 +348,7 @@ static struct i2c_driver max8998_i2c_driver = {
.suppress_bind_attrs = true,
.of_match_table = of_match_ptr(max8998_dt_match),
},
- .probe = max8998_i2c_probe,
+ .probe_new = max8998_i2c_probe,
.id_table = max8998_i2c_id,
};
diff --git a/drivers/mfd/mc13xxx-i2c.c b/drivers/mfd/mc13xxx-i2c.c
index eb94f3004cf3..633b973a5ba7 100644
--- a/drivers/mfd/mc13xxx-i2c.c
+++ b/drivers/mfd/mc13xxx-i2c.c
@@ -11,7 +11,6 @@
#include <linux/mfd/mc13xxx.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/of_gpio.h>
#include <linux/i2c.h>
#include <linux/err.h>
@@ -52,9 +51,9 @@ static const struct regmap_config mc13xxx_regmap_i2c_config = {
.cache_type = REGCACHE_NONE,
};
-static int mc13xxx_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int mc13xxx_i2c_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct mc13xxx *mc13xxx;
int ret;
@@ -96,7 +95,7 @@ static struct i2c_driver mc13xxx_i2c_driver = {
.name = "mc13xxx",
.of_match_table = mc13xxx_dt_ids,
},
- .probe = mc13xxx_i2c_probe,
+ .probe_new = mc13xxx_i2c_probe,
.remove = mc13xxx_i2c_remove,
};
diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c
index f803527e5819..f70d79aa5a83 100644
--- a/drivers/mfd/mc13xxx-spi.c
+++ b/drivers/mfd/mc13xxx-spi.c
@@ -15,7 +15,6 @@
#include <linux/mfd/mc13xxx.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/of_gpio.h>
#include <linux/err.h>
#include <linux/spi/spi.h>
@@ -115,7 +114,7 @@ static int mc13xxx_spi_write(void *context, const void *data, size_t count)
* result, the SS will negate before all of the data has been
* transferred to/from the peripheral."
* We workaround this by accessing the SPI controller with a
- * single transfert.
+ * single transfer.
*/
static struct regmap_bus regmap_mc13xxx_bus = {
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index 4629dff187cd..1c9831b78cf9 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -255,7 +255,6 @@ static int mcp_sa11x0_remove(struct platform_device *dev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int mcp_sa11x0_suspend(struct device *dev)
{
struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
@@ -277,17 +276,14 @@ static int mcp_sa11x0_resume(struct device *dev)
return 0;
}
-#endif
static const struct dev_pm_ops mcp_sa11x0_pm_ops = {
-#ifdef CONFIG_PM_SLEEP
.suspend = mcp_sa11x0_suspend,
.freeze = mcp_sa11x0_suspend,
.poweroff = mcp_sa11x0_suspend,
.resume_noirq = mcp_sa11x0_resume,
.thaw_noirq = mcp_sa11x0_resume,
.restore_noirq = mcp_sa11x0_resume,
-#endif
};
static struct platform_driver mcp_sa11x0_driver = {
@@ -295,7 +291,7 @@ static struct platform_driver mcp_sa11x0_driver = {
.remove = mcp_sa11x0_remove,
.driver = {
.name = DRIVER_NAME,
- .pm = &mcp_sa11x0_pm_ops,
+ .pm = pm_sleep_ptr(&mcp_sa11x0_pm_ops),
},
};
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index eb08f69001f9..c2866a11c1d2 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1142,8 +1142,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
static struct i2c_driver menelaus_i2c_driver;
-static int menelaus_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int menelaus_probe(struct i2c_client *client)
{
struct menelaus_chip *menelaus;
int rev = 0;
@@ -1241,7 +1240,7 @@ static struct i2c_driver menelaus_i2c_driver = {
.driver = {
.name = DRIVER_NAME,
},
- .probe = menelaus_probe,
+ .probe_new = menelaus_probe,
.remove = menelaus_remove,
.id_table = menelaus_id,
};
diff --git a/drivers/mfd/menf21bmc.c b/drivers/mfd/menf21bmc.c
index 8f72b1cccbe5..9092fac46e35 100644
--- a/drivers/mfd/menf21bmc.c
+++ b/drivers/mfd/menf21bmc.c
@@ -49,7 +49,7 @@ static int menf21bmc_wdt_exit_prod_mode(struct i2c_client *client)
}
static int
-menf21bmc_probe(struct i2c_client *client, const struct i2c_device_id *ids)
+menf21bmc_probe(struct i2c_client *client)
{
int rev_major, rev_minor, rev_main;
int ret;
@@ -111,7 +111,7 @@ MODULE_DEVICE_TABLE(i2c, menf21bmc_id_table);
static struct i2c_driver menf21bmc_driver = {
.driver.name = "menf21bmc",
.id_table = menf21bmc_id_table,
- .probe = menf21bmc_probe,
+ .probe_new = menf21bmc_probe,
};
module_i2c_driver(menf21bmc_driver);
diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c
index 265464b5d7cc..a19691ba8d8b 100644
--- a/drivers/mfd/motorola-cpcap.c
+++ b/drivers/mfd/motorola-cpcap.c
@@ -221,7 +221,6 @@ static const struct regmap_config cpcap_regmap_config = {
.val_format_endian = REGMAP_ENDIAN_LITTLE,
};
-#ifdef CONFIG_PM_SLEEP
static int cpcap_suspend(struct device *dev)
{
struct spi_device *spi = to_spi_device(dev);
@@ -239,9 +238,8 @@ static int cpcap_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(cpcap_pm, cpcap_suspend, cpcap_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(cpcap_pm, cpcap_suspend, cpcap_resume);
static const struct mfd_cell cpcap_mfd_devices[] = {
{
@@ -296,7 +294,7 @@ static int cpcap_probe(struct spi_device *spi)
struct cpcap_ddata *cpcap;
int ret;
- match = of_match_device(of_match_ptr(cpcap_of_match), &spi->dev);
+ match = of_match_device(cpcap_of_match, &spi->dev);
if (!match)
return -ENODEV;
@@ -346,7 +344,7 @@ static struct spi_driver cpcap_driver = {
.driver = {
.name = "cpcap-core",
.of_match_table = cpcap_of_match,
- .pm = &cpcap_pm,
+ .pm = pm_sleep_ptr(&cpcap_pm),
},
.probe = cpcap_probe,
.id_table = cpcap_spi_ids,
diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c
index 6eaa6775b888..d3b32eb79837 100644
--- a/drivers/mfd/mt6360-core.c
+++ b/drivers/mfd/mt6360-core.c
@@ -402,7 +402,7 @@ static int mt6360_regmap_read(void *context, const void *reg, size_t reg_size,
struct mt6360_ddata *ddata = context;
u8 bank = *(u8 *)reg;
u8 reg_addr = *(u8 *)(reg + 1);
- struct i2c_client *i2c = ddata->i2c[bank];
+ struct i2c_client *i2c;
bool crc_needed = false;
u8 *buf;
int buf_len = MT6360_ALLOC_READ_SIZE(val_size);
@@ -410,6 +410,11 @@ static int mt6360_regmap_read(void *context, const void *reg, size_t reg_size,
u8 crc;
int ret;
+ if (bank >= MT6360_SLAVE_MAX)
+ return -EINVAL;
+
+ i2c = ddata->i2c[bank];
+
if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
crc_needed = true;
ret = mt6360_xlate_pmicldo_addr(&reg_addr, val_size);
@@ -453,13 +458,18 @@ static int mt6360_regmap_write(void *context, const void *val, size_t val_size)
struct mt6360_ddata *ddata = context;
u8 bank = *(u8 *)val;
u8 reg_addr = *(u8 *)(val + 1);
- struct i2c_client *i2c = ddata->i2c[bank];
+ struct i2c_client *i2c;
bool crc_needed = false;
u8 *buf;
int buf_len = MT6360_ALLOC_WRITE_SIZE(val_size);
int write_size = val_size - MT6360_REGMAP_REG_BYTE_SIZE;
int ret;
+ if (bank >= MT6360_SLAVE_MAX)
+ return -EINVAL;
+
+ i2c = ddata->i2c[bank];
+
if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
crc_needed = true;
ret = mt6360_xlate_pmicldo_addr(&reg_addr, val_size - MT6360_REGMAP_REG_BYTE_SIZE);
diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c
index eff53fed8fe7..72f923e47752 100644
--- a/drivers/mfd/mt6397-irq.c
+++ b/drivers/mfd/mt6397-irq.c
@@ -54,7 +54,6 @@ static void mt6397_irq_enable(struct irq_data *data)
mt6397->irq_masks_cur[reg] |= BIT(shift);
}
-#ifdef CONFIG_PM_SLEEP
static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
{
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
@@ -68,9 +67,6 @@ static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
return 0;
}
-#else
-#define mt6397_irq_set_wake NULL
-#endif
static struct irq_chip mt6397_irq_chip = {
.name = "mt6397-irq",
@@ -78,7 +74,7 @@ static struct irq_chip mt6397_irq_chip = {
.irq_bus_sync_unlock = mt6397_irq_sync_unlock,
.irq_enable = mt6397_irq_enable,
.irq_disable = mt6397_irq_disable,
- .irq_set_wake = mt6397_irq_set_wake,
+ .irq_set_wake = pm_sleep_ptr(mt6397_irq_set_wake),
};
static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 8b7429bd2e3e..b8383c6cba3f 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -502,8 +502,7 @@ static const struct of_device_id of_palmas_match_tbl[] = {
};
MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
-static int palmas_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int palmas_i2c_probe(struct i2c_client *i2c)
{
struct palmas *palmas;
struct palmas_platform_data *pdata;
@@ -512,7 +511,6 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
int ret = 0, i;
unsigned int reg, addr;
int slave;
- const struct of_device_id *match;
pdata = dev_get_platdata(&i2c->dev);
@@ -536,12 +534,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
palmas->dev = &i2c->dev;
palmas->irq = i2c->irq;
- match = of_match_device(of_palmas_match_tbl, &i2c->dev);
-
- if (!match)
- return -ENODATA;
-
- driver_data = (struct palmas_driver_data *)match->data;
+ driver_data = (struct palmas_driver_data *) device_get_match_data(&i2c->dev);
palmas->features = *driver_data->features;
for (i = 0; i < PALMAS_NUM_CLIENTS; i++) {
@@ -732,7 +725,7 @@ static struct i2c_driver palmas_i2c_driver = {
.name = "palmas",
.of_match_table = of_palmas_match_tbl,
},
- .probe = palmas_i2c_probe,
+ .probe_new = palmas_i2c_probe,
.remove = palmas_i2c_remove,
.id_table = palmas_i2c_id,
};
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 4ccc2c3e7681..0e4fc99e9f49 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -158,33 +158,12 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
}
}
-#ifdef CONFIG_PM_SLEEP
-static int pcf50633_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct pcf50633 *pcf = i2c_get_clientdata(client);
-
- return pcf50633_irq_suspend(pcf);
-}
-
-static int pcf50633_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct pcf50633 *pcf = i2c_get_clientdata(client);
-
- return pcf50633_irq_resume(pcf);
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
-
static const struct regmap_config pcf50633_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
-static int pcf50633_probe(struct i2c_client *client,
- const struct i2c_device_id *ids)
+static int pcf50633_probe(struct i2c_client *client)
{
struct pcf50633 *pcf;
struct platform_device *pdev;
@@ -300,10 +279,10 @@ MODULE_DEVICE_TABLE(i2c, pcf50633_id_table);
static struct i2c_driver pcf50633_driver = {
.driver = {
.name = "pcf50633",
- .pm = &pcf50633_pm,
+ .pm = pm_sleep_ptr(&pcf50633_pm),
},
.id_table = pcf50633_id_table,
- .probe = pcf50633_probe,
+ .probe_new = pcf50633_probe,
.remove = pcf50633_remove,
};
diff --git a/drivers/mfd/pcf50633-irq.c b/drivers/mfd/pcf50633-irq.c
index 2096afb0ce9b..e85af7f1cb0b 100644
--- a/drivers/mfd/pcf50633-irq.c
+++ b/drivers/mfd/pcf50633-irq.c
@@ -7,6 +7,7 @@
* All rights reserved.
*/
+#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
@@ -218,10 +219,10 @@ out:
return IRQ_HANDLED;
}
-#ifdef CONFIG_PM
-
-int pcf50633_irq_suspend(struct pcf50633 *pcf)
+static int pcf50633_suspend(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct pcf50633 *pcf = i2c_get_clientdata(client);
int ret;
int i;
u8 res[5];
@@ -257,8 +258,10 @@ out:
return ret;
}
-int pcf50633_irq_resume(struct pcf50633 *pcf)
+static int pcf50633_resume(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct pcf50633 *pcf = i2c_get_clientdata(client);
int ret;
/* Write the saved mask registers */
@@ -273,7 +276,7 @@ int pcf50633_irq_resume(struct pcf50633 *pcf)
return ret;
}
-#endif
+EXPORT_GPL_SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
int pcf50633_irq_init(struct pcf50633 *pcf, int irq)
{
diff --git a/drivers/mfd/qcom-pm8008.c b/drivers/mfd/qcom-pm8008.c
index 4b8ff947762f..9f3c4a01b4c1 100644
--- a/drivers/mfd/qcom-pm8008.c
+++ b/drivers/mfd/qcom-pm8008.c
@@ -215,8 +215,8 @@ static int pm8008_probe(struct i2c_client *client)
dev = &client->dev;
regmap = devm_regmap_init_i2c(client, &qcom_mfd_regmap_cfg);
- if (!regmap)
- return -ENODEV;
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
i2c_set_clientdata(client, regmap);
diff --git a/drivers/mfd/qcom-pm8xxx.c b/drivers/mfd/qcom-pm8xxx.c
index 2f2734ba5273..601106580e2e 100644
--- a/drivers/mfd/qcom-pm8xxx.c
+++ b/drivers/mfd/qcom-pm8xxx.c
@@ -497,7 +497,6 @@ static const struct pm_irq_data pm8821_data = {
};
static const struct of_device_id pm8xxx_id_table[] = {
- { .compatible = "qcom,pm8018", .data = &pm8xxx_data},
{ .compatible = "qcom,pm8058", .data = &pm8xxx_data},
{ .compatible = "qcom,pm8821", .data = &pm8821_data},
{ .compatible = "qcom,pm8921", .data = &pm8xxx_data},
diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c
index 71bc34b74bc9..8fea0e511550 100644
--- a/drivers/mfd/qcom_rpm.c
+++ b/drivers/mfd/qcom_rpm.c
@@ -547,7 +547,7 @@ static int qcom_rpm_probe(struct platform_device *pdev)
init_completion(&rpm->ack);
/* Enable message RAM clock */
- rpm->ramclk = devm_clk_get(&pdev->dev, "ram");
+ rpm->ramclk = devm_clk_get_enabled(&pdev->dev, "ram");
if (IS_ERR(rpm->ramclk)) {
ret = PTR_ERR(rpm->ramclk);
if (ret == -EPROBE_DEFER)
@@ -558,7 +558,6 @@ static int qcom_rpm_probe(struct platform_device *pdev)
*/
rpm->ramclk = NULL;
}
- clk_prepare_enable(rpm->ramclk); /* Accepts NULL */
irq_ack = platform_get_irq_byname(pdev, "ack");
if (irq_ack < 0)
@@ -673,22 +672,11 @@ static int qcom_rpm_probe(struct platform_device *pdev)
if (ret)
dev_warn(&pdev->dev, "failed to mark wakeup irq as wakeup\n");
- return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
-}
-
-static int qcom_rpm_remove(struct platform_device *pdev)
-{
- struct qcom_rpm *rpm = dev_get_drvdata(&pdev->dev);
-
- of_platform_depopulate(&pdev->dev);
- clk_disable_unprepare(rpm->ramclk);
-
- return 0;
+ return devm_of_platform_populate(&pdev->dev);
}
static struct platform_driver qcom_rpm_driver = {
.probe = qcom_rpm_probe,
- .remove = qcom_rpm_remove,
.driver = {
.name = "qcom_rpm",
.of_match_table = qcom_rpm_of_match,
diff --git a/drivers/mfd/rc5t583-irq.c b/drivers/mfd/rc5t583-irq.c
index b374a3d34688..621ea61fa7c6 100644
--- a/drivers/mfd/rc5t583-irq.c
+++ b/drivers/mfd/rc5t583-irq.c
@@ -228,15 +228,12 @@ static void rc5t583_irq_sync_unlock(struct irq_data *irq_data)
mutex_unlock(&rc5t583->irq_lock);
}
-#ifdef CONFIG_PM_SLEEP
+
static int rc5t583_irq_set_wake(struct irq_data *irq_data, unsigned int on)
{
struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
return irq_set_irq_wake(rc5t583->chip_irq, on);
}
-#else
-#define rc5t583_irq_set_wake NULL
-#endif
static irqreturn_t rc5t583_irq(int irq, void *data)
{
@@ -317,7 +314,7 @@ static struct irq_chip rc5t583_irq_chip = {
.irq_bus_lock = rc5t583_irq_lock,
.irq_bus_sync_unlock = rc5t583_irq_sync_unlock,
.irq_set_type = rc5t583_irq_set_type,
- .irq_set_wake = rc5t583_irq_set_wake,
+ .irq_set_wake = pm_sleep_ptr(rc5t583_irq_set_wake),
};
int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base)
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index d0dc48f99096..df83cc399315 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -233,8 +233,7 @@ static const struct regmap_config rc5t583_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
-static int rc5t583_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int rc5t583_i2c_probe(struct i2c_client *i2c)
{
struct rc5t583 *rc5t583;
struct rc5t583_platform_data *pdata = dev_get_platdata(&i2c->dev);
@@ -289,7 +288,7 @@ static struct i2c_driver rc5t583_i2c_driver = {
.driver = {
.name = "rc5t583",
},
- .probe = rc5t583_i2c_probe,
+ .probe_new = rc5t583_i2c_probe,
.id_table = rc5t583_i2c_id,
};
diff --git a/drivers/mfd/retu-mfd.c b/drivers/mfd/retu-mfd.c
index 3b5acf7ca39c..d71483859e2e 100644
--- a/drivers/mfd/retu-mfd.c
+++ b/drivers/mfd/retu-mfd.c
@@ -227,7 +227,7 @@ static const struct regmap_config retu_config = {
.val_bits = 16,
};
-static int retu_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+static int retu_probe(struct i2c_client *i2c)
{
struct retu_data const *rdat;
struct retu_dev *rdev;
@@ -318,7 +318,7 @@ static struct i2c_driver retu_driver = {
.name = "retu-mfd",
.of_match_table = retu_of_match,
},
- .probe = retu_probe,
+ .probe_new = retu_probe,
.remove = retu_remove,
.id_table = retu_id,
};
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index e00da7c7e3b1..f44fc3f080a8 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -137,58 +137,64 @@ static const struct resource rk817_charger_resources[] = {
};
static const struct mfd_cell rk805s[] = {
- { .name = "rk808-clkout", },
- { .name = "rk808-regulator", },
- { .name = "rk805-pinctrl", },
+ { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
+ { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
+ { .name = "rk805-pinctrl", .id = PLATFORM_DEVID_NONE, },
{
.name = "rk808-rtc",
.num_resources = ARRAY_SIZE(rtc_resources),
.resources = &rtc_resources[0],
+ .id = PLATFORM_DEVID_NONE,
},
{ .name = "rk805-pwrkey",
.num_resources = ARRAY_SIZE(rk805_key_resources),
.resources = &rk805_key_resources[0],
+ .id = PLATFORM_DEVID_NONE,
},
};
static const struct mfd_cell rk808s[] = {
- { .name = "rk808-clkout", },
- { .name = "rk808-regulator", },
+ { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
+ { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
{
.name = "rk808-rtc",
.num_resources = ARRAY_SIZE(rtc_resources),
.resources = rtc_resources,
+ .id = PLATFORM_DEVID_NONE,
},
};
static const struct mfd_cell rk817s[] = {
- { .name = "rk808-clkout",},
- { .name = "rk808-regulator",},
+ { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
+ { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
{
.name = "rk805-pwrkey",
.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
.resources = &rk817_pwrkey_resources[0],
+ .id = PLATFORM_DEVID_NONE,
},
{
.name = "rk808-rtc",
.num_resources = ARRAY_SIZE(rk817_rtc_resources),
.resources = &rk817_rtc_resources[0],
+ .id = PLATFORM_DEVID_NONE,
},
- { .name = "rk817-codec",},
+ { .name = "rk817-codec", .id = PLATFORM_DEVID_NONE, },
{
.name = "rk817-charger",
.num_resources = ARRAY_SIZE(rk817_charger_resources),
.resources = &rk817_charger_resources[0],
+ .id = PLATFORM_DEVID_NONE,
},
};
static const struct mfd_cell rk818s[] = {
- { .name = "rk808-clkout", },
- { .name = "rk808-regulator", },
+ { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
{
.name = "rk808-rtc",
.num_resources = ARRAY_SIZE(rtc_resources),
.resources = rtc_resources,
+ .id = PLATFORM_DEVID_NONE,
},
};
@@ -640,8 +646,7 @@ static const struct of_device_id rk808_of_match[] = {
};
MODULE_DEVICE_TABLE(of, rk808_of_match);
-static int rk808_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int rk808_probe(struct i2c_client *client)
{
struct device_node *np = client->dev.of_node;
struct rk808 *rk808;
@@ -861,7 +866,7 @@ static struct i2c_driver rk808_i2c_driver = {
.of_match_table = rk808_of_match,
.pm = &rk8xx_pm_ops,
},
- .probe = rk808_probe,
+ .probe_new = rk808_probe,
.remove = rk808_remove,
.shutdown = rk8xx_shutdown,
};
diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c
index eb8005b4e58d..2f59230749cd 100644
--- a/drivers/mfd/rn5t618.c
+++ b/drivers/mfd/rn5t618.c
@@ -80,8 +80,7 @@ static const struct regmap_irq_chip rc5t619_irq_chip = {
.num_irqs = ARRAY_SIZE(rc5t619_irqs),
.num_regs = 1,
.status_base = RN5T618_INTMON,
- .mask_base = RN5T618_INTEN,
- .mask_invert = true,
+ .unmask_base = RN5T618_INTEN,
};
static struct i2c_client *rn5t618_pm_power_off;
diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
index 714d9fcbf07b..7eb920633ee9 100644
--- a/drivers/mfd/rohm-bd71828.c
+++ b/drivers/mfd/rohm-bd71828.c
@@ -413,9 +413,8 @@ static struct regmap_irq_chip bd71828_irq_chip = {
.irqs = &bd71828_irqs[0],
.num_irqs = ARRAY_SIZE(bd71828_irqs),
.status_base = BD71828_REG_INT_BUCK,
- .mask_base = BD71828_REG_INT_MASK_BUCK,
+ .unmask_base = BD71828_REG_INT_MASK_BUCK,
.ack_base = BD71828_REG_INT_BUCK,
- .mask_invert = true,
.init_ack_masked = true,
.num_regs = 12,
.num_main_regs = 1,
@@ -430,9 +429,8 @@ static struct regmap_irq_chip bd71815_irq_chip = {
.irqs = &bd71815_irqs[0],
.num_irqs = ARRAY_SIZE(bd71815_irqs),
.status_base = BD71815_REG_INT_STAT_01,
- .mask_base = BD71815_REG_INT_EN_01,
+ .unmask_base = BD71815_REG_INT_EN_01,
.ack_base = BD71815_REG_INT_STAT_01,
- .mask_invert = true,
.init_ack_masked = true,
.num_regs = 12,
.num_main_regs = 1,
@@ -515,27 +513,24 @@ static int bd71828_i2c_probe(struct i2c_client *i2c)
}
regmap = devm_regmap_init_i2c(i2c, regmap_config);
- if (IS_ERR(regmap)) {
- dev_err(&i2c->dev, "Failed to initialize Regmap\n");
- return PTR_ERR(regmap);
- }
+ if (IS_ERR(regmap))
+ return dev_err_probe(&i2c->dev, PTR_ERR(regmap),
+ "Failed to initialize Regmap\n");
ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, i2c->irq,
IRQF_ONESHOT, 0, irqchip, &irq_data);
- if (ret) {
- dev_err(&i2c->dev, "Failed to add IRQ chip\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(&i2c->dev, ret,
+ "Failed to add IRQ chip\n");
dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n",
irqchip->num_irqs);
if (button_irq) {
ret = regmap_irq_get_virq(irq_data, button_irq);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to get the power-key IRQ\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(&i2c->dev, ret,
+ "Failed to get the power-key IRQ\n");
button.irq = ret;
}
@@ -547,7 +542,7 @@ static int bd71828_i2c_probe(struct i2c_client *i2c)
ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, mfd, cells,
NULL, 0, regmap_irq_get_domain(irq_data));
if (ret)
- dev_err(&i2c->dev, "Failed to create subdevices\n");
+ dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
return ret;
}
diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
index bfd81f78beae..378eb1a692e4 100644
--- a/drivers/mfd/rohm-bd718x7.c
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -70,7 +70,6 @@ static struct regmap_irq_chip bd718xx_irq_chip = {
.mask_base = BD718XX_REG_MIRQ,
.ack_base = BD718XX_REG_IRQ,
.init_ack_masked = true,
- .mask_invert = false,
};
static const struct regmap_range pmic_status_range = {
@@ -127,8 +126,7 @@ static int bd718xx_init_press_duration(struct regmap *regmap,
return 0;
}
-static int bd718xx_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int bd718xx_i2c_probe(struct i2c_client *i2c)
{
struct regmap *regmap;
struct regmap_irq_chip_data *irq_data;
@@ -158,18 +156,15 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c,
}
regmap = devm_regmap_init_i2c(i2c, &bd718xx_regmap_config);
- if (IS_ERR(regmap)) {
- dev_err(&i2c->dev, "regmap initialization failed\n");
- return PTR_ERR(regmap);
- }
+ if (IS_ERR(regmap))
+ return dev_err_probe(&i2c->dev, PTR_ERR(regmap),
+ "regmap initialization failed\n");
ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, i2c->irq,
IRQF_ONESHOT, 0, &bd718xx_irq_chip,
&irq_data);
- if (ret) {
- dev_err(&i2c->dev, "Failed to add irq_chip\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(&i2c->dev, ret, "Failed to add irq_chip\n");
ret = bd718xx_init_press_duration(regmap, &i2c->dev);
if (ret)
@@ -177,10 +172,8 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c,
ret = regmap_irq_get_virq(irq_data, BD718XX_INT_PWRBTN_S);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to get the IRQ\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(&i2c->dev, ret, "Failed to get the IRQ\n");
button.irq = ret;
@@ -188,7 +181,7 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c,
mfd, cells, NULL, 0,
regmap_irq_get_domain(irq_data));
if (ret)
- dev_err(&i2c->dev, "Failed to create subdevices\n");
+ dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
return ret;
}
@@ -215,7 +208,7 @@ static struct i2c_driver bd718xx_i2c_driver = {
.name = "rohm-bd718x7",
.of_match_table = bd718xx_of_match,
},
- .probe = bd718xx_i2c_probe,
+ .probe_new = bd718xx_i2c_probe,
};
static int __init bd718xx_i2c_init(void)
diff --git a/drivers/mfd/rohm-bd9576.c b/drivers/mfd/rohm-bd9576.c
index f37cd4f27aeb..6491e385d980 100644
--- a/drivers/mfd/rohm-bd9576.c
+++ b/drivers/mfd/rohm-bd9576.c
@@ -88,8 +88,7 @@ static struct regmap_irq_chip bd9576_irq_chip = {
.irq_reg_stride = 1,
};
-static int bd957x_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int bd957x_i2c_probe(struct i2c_client *i2c)
{
int ret;
struct regmap *regmap;
@@ -122,10 +121,9 @@ static int bd957x_i2c_probe(struct i2c_client *i2c,
}
regmap = devm_regmap_init_i2c(i2c, &bd957x_regmap);
- if (IS_ERR(regmap)) {
- dev_err(&i2c->dev, "Failed to initialize Regmap\n");
- return PTR_ERR(regmap);
- }
+ if (IS_ERR(regmap))
+ return dev_err_probe(&i2c->dev, PTR_ERR(regmap),
+ "Failed to initialize Regmap\n");
/*
* BD9576 behaves badly. It kepts IRQ line asserted for the whole
@@ -146,10 +144,10 @@ static int bd957x_i2c_probe(struct i2c_client *i2c,
ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, i2c->irq,
IRQF_ONESHOT, 0,
&bd9576_irq_chip, &irq_data);
- if (ret) {
- dev_err(&i2c->dev, "Failed to add IRQ chip\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(&i2c->dev, ret,
+ "Failed to add IRQ chip\n");
+
domain = regmap_irq_get_domain(irq_data);
} else {
ret = regmap_update_bits(regmap, BD957X_REG_INT_MAIN_MASK,
@@ -163,7 +161,7 @@ static int bd957x_i2c_probe(struct i2c_client *i2c,
ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, cells,
num_cells, NULL, 0, domain);
if (ret)
- dev_err(&i2c->dev, "Failed to create subdevices\n");
+ dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
return ret;
}
@@ -180,7 +178,7 @@ static struct i2c_driver bd957x_drv = {
.name = "rohm-bd957x",
.of_match_table = bd957x_of_match,
},
- .probe = &bd957x_i2c_probe,
+ .probe_new = &bd957x_i2c_probe,
};
module_i2c_driver(bd957x_drv);
diff --git a/drivers/mfd/rsmu_i2c.c b/drivers/mfd/rsmu_i2c.c
index f716ab8039a0..15d25b081434 100644
--- a/drivers/mfd/rsmu_i2c.c
+++ b/drivers/mfd/rsmu_i2c.c
@@ -106,9 +106,9 @@ static const struct regmap_config rsmu_sl_regmap_config = {
.can_multi_write = true,
};
-static int rsmu_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int rsmu_i2c_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
const struct regmap_config *cfg;
struct rsmu_ddata *rsmu;
int ret;
@@ -180,7 +180,7 @@ static struct i2c_driver rsmu_i2c_driver = {
.name = "rsmu-i2c",
.of_match_table = of_match_ptr(rsmu_i2c_of_match),
},
- .probe = rsmu_i2c_probe,
+ .probe_new = rsmu_i2c_probe,
.remove = rsmu_i2c_remove,
.id_table = rsmu_i2c_id,
};
diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c
index f1236a9acf30..a5e520fe50a1 100644
--- a/drivers/mfd/rt5033.c
+++ b/drivers/mfd/rt5033.c
@@ -29,8 +29,7 @@ static const struct regmap_irq rt5033_irqs[] = {
static const struct regmap_irq_chip rt5033_irq_chip = {
.name = "rt5033",
.status_base = RT5033_REG_PMIC_IRQ_STAT,
- .mask_base = RT5033_REG_PMIC_IRQ_CTRL,
- .mask_invert = true,
+ .unmask_base = RT5033_REG_PMIC_IRQ_CTRL,
.num_regs = 1,
.irqs = rt5033_irqs,
.num_irqs = ARRAY_SIZE(rt5033_irqs),
@@ -56,8 +55,7 @@ static const struct regmap_config rt5033_regmap_config = {
.max_register = RT5033_REG_END,
};
-static int rt5033_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int rt5033_i2c_probe(struct i2c_client *i2c)
{
struct rt5033_dev *rt5033;
unsigned int dev_id;
@@ -124,7 +122,7 @@ static struct i2c_driver rt5033_driver = {
.name = "rt5033",
.of_match_table = rt5033_dt_match,
},
- .probe = rt5033_i2c_probe,
+ .probe_new = rt5033_i2c_probe,
.id_table = rt5033_i2c_id,
};
module_i2c_driver(rt5033_driver);
diff --git a/drivers/mfd/rt5120.c b/drivers/mfd/rt5120.c
index 8046e383bc92..829b7a0a0781 100644
--- a/drivers/mfd/rt5120.c
+++ b/drivers/mfd/rt5120.c
@@ -59,9 +59,8 @@ static const struct regmap_irq rt5120_irqs[] = {
static const struct regmap_irq_chip rt5120_irq_chip = {
.name = "rt5120-pmic",
.status_base = RT5120_REG_INTSTAT,
- .mask_base = RT5120_REG_INTENABLE,
+ .unmask_base = RT5120_REG_INTENABLE,
.ack_base = RT5120_REG_INTSTAT,
- .mask_invert = true,
.use_ack = true,
.num_regs = 1,
.irqs = rt5120_irqs,
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
index 1fb29c45f5cf..b03edda56009 100644
--- a/drivers/mfd/sec-core.c
+++ b/drivers/mfd/sec-core.c
@@ -305,8 +305,7 @@ sec_pmic_i2c_parse_dt_pdata(struct device *dev)
return pd;
}
-static int sec_pmic_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int sec_pmic_probe(struct i2c_client *i2c)
{
const struct regmap_config *regmap;
struct sec_platform_data *pdata;
@@ -455,7 +454,6 @@ static void sec_pmic_shutdown(struct i2c_client *i2c)
regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
}
-#ifdef CONFIG_PM_SLEEP
static int sec_pmic_suspend(struct device *dev)
{
struct i2c_client *i2c = to_i2c_client(dev);
@@ -488,17 +486,17 @@ static int sec_pmic_resume(struct device *dev)
return 0;
}
-#endif /* CONFIG_PM_SLEEP */
-static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops,
+ sec_pmic_suspend, sec_pmic_resume);
static struct i2c_driver sec_pmic_driver = {
.driver = {
.name = "sec_pmic",
- .pm = &sec_pmic_pm_ops,
+ .pm = pm_sleep_ptr(&sec_pmic_pm_ops),
.of_match_table = sec_dt_match,
},
- .probe = sec_pmic_probe,
+ .probe_new = sec_pmic_probe,
.shutdown = sec_pmic_shutdown,
};
module_i2c_driver(sec_pmic_driver);
diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c
index 8166949b725c..22131cf85e3f 100644
--- a/drivers/mfd/si476x-i2c.c
+++ b/drivers/mfd/si476x-i2c.c
@@ -683,9 +683,9 @@ bool si476x_core_is_powered_up(struct si476x_core *core)
}
EXPORT_SYMBOL_GPL(si476x_core_is_powered_up);
-static int si476x_core_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int si476x_core_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
int rval;
struct si476x_core *core;
struct si476x_platform_data *pdata;
@@ -866,7 +866,7 @@ static struct i2c_driver si476x_core_driver = {
.driver = {
.name = "si476x-core",
},
- .probe = si476x_core_probe,
+ .probe_new = si476x_core_probe,
.remove = si476x_core_remove,
.id_table = si476x_id,
};
diff --git a/drivers/mfd/sky81452.c b/drivers/mfd/sky81452.c
index 3ad35bf0c015..2515ecae1d3f 100644
--- a/drivers/mfd/sky81452.c
+++ b/drivers/mfd/sky81452.c
@@ -21,8 +21,7 @@ static const struct regmap_config sky81452_config = {
.val_bits = 8,
};
-static int sky81452_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int sky81452_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
const struct sky81452_platform_data *pdata = dev_get_platdata(dev);
@@ -78,7 +77,7 @@ static struct i2c_driver sky81452_driver = {
.name = "sky81452",
.of_match_table = of_match_ptr(sky81452_of_match),
},
- .probe = sky81452_probe,
+ .probe_new = sky81452_probe,
.id_table = sky81452_ids,
};
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 3ac4508a6742..28027982cf69 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1432,8 +1432,6 @@ static int sm501_plat_probe(struct platform_device *dev)
}
-#ifdef CONFIG_PM
-
/* power management support */
static void sm501_set_power(struct sm501_devdata *sm, int on)
@@ -1509,10 +1507,6 @@ static int sm501_plat_resume(struct platform_device *pdev)
return 0;
}
-#else
-#define sm501_plat_suspend NULL
-#define sm501_plat_resume NULL
-#endif
/* Initialisation data for PCI devices */
@@ -1714,8 +1708,8 @@ static struct platform_driver sm501_plat_driver = {
},
.probe = sm501_plat_probe,
.remove = sm501_plat_remove,
- .suspend = sm501_plat_suspend,
- .resume = sm501_plat_resume,
+ .suspend = pm_sleep_ptr(sm501_plat_suspend),
+ .resume = pm_sleep_ptr(sm501_plat_resume),
};
static int __init sm501_base_init(void)
diff --git a/drivers/mfd/smpro-core.c b/drivers/mfd/smpro-core.c
new file mode 100644
index 000000000000..d7729cf70378
--- /dev/null
+++ b/drivers/mfd/smpro-core.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Ampere Altra Family SMPro core driver
+ * Copyright (c) 2022, Ampere Computing LLC
+ */
+
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+
+/* Identification Registers */
+#define MANUFACTURER_ID_REG 0x02
+#define AMPERE_MANUFACTURER_ID 0xCD3A
+
+#define CORE_CE_ERR_DATA 0x82
+#define CORE_UE_ERR_DATA 0x85
+#define MEM_CE_ERR_DATA 0x92
+#define MEM_UE_ERR_DATA 0x95
+#define PCIE_CE_ERR_DATA 0xC2
+#define PCIE_UE_ERR_DATA 0xC5
+#define OTHER_CE_ERR_DATA 0xD2
+#define OTHER_UE_ERR_DATA 0xDA
+
+static int smpro_core_write(void *context, const void *data, size_t count)
+{
+ struct device *dev = context;
+ struct i2c_client *i2c = to_i2c_client(dev);
+ int ret;
+
+ ret = i2c_master_send(i2c, data, count);
+ if (unlikely(ret != count))
+ return (ret < 0) ? ret : -EIO;
+
+ return 0;
+}
+
+static int smpro_core_read(void *context, const void *reg, size_t reg_size,
+ void *val, size_t val_size)
+{
+ struct device *dev = context;
+ struct i2c_client *i2c = to_i2c_client(dev);
+ struct i2c_msg xfer[2];
+ unsigned char buf[2];
+ int ret;
+
+ xfer[0].addr = i2c->addr;
+ xfer[0].flags = 0;
+
+ buf[0] = *(u8 *)reg;
+ buf[1] = val_size;
+ xfer[0].len = 2;
+ xfer[0].buf = buf;
+
+ xfer[1].addr = i2c->addr;
+ xfer[1].flags = I2C_M_RD;
+ xfer[1].len = val_size;
+ xfer[1].buf = val;
+
+ ret = i2c_transfer(i2c->adapter, xfer, 2);
+ if (unlikely(ret != 2))
+ return (ret < 0) ? ret : -EIO;
+
+ return 0;
+}
+
+static const struct regmap_bus smpro_regmap_bus = {
+ .read = smpro_core_read,
+ .write = smpro_core_write,
+ .val_format_endian_default = REGMAP_ENDIAN_BIG,
+};
+
+static bool smpro_core_readable_noinc_reg(struct device *dev, unsigned int reg)
+{
+ return (reg == CORE_CE_ERR_DATA || reg == CORE_UE_ERR_DATA ||
+ reg == MEM_CE_ERR_DATA || reg == MEM_UE_ERR_DATA ||
+ reg == PCIE_CE_ERR_DATA || reg == PCIE_UE_ERR_DATA ||
+ reg == OTHER_CE_ERR_DATA || reg == OTHER_UE_ERR_DATA);
+}
+
+static const struct regmap_config smpro_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .readable_noinc_reg = smpro_core_readable_noinc_reg,
+};
+
+static const struct mfd_cell smpro_devs[] = {
+ MFD_CELL_NAME("smpro-hwmon"),
+ MFD_CELL_NAME("smpro-errmon"),
+ MFD_CELL_NAME("smpro-misc"),
+};
+
+static int smpro_core_probe(struct i2c_client *i2c)
+{
+ const struct regmap_config *config;
+ struct regmap *regmap;
+ unsigned int val;
+ int ret;
+
+ config = device_get_match_data(&i2c->dev);
+ if (!config)
+ return -EINVAL;
+
+ regmap = devm_regmap_init(&i2c->dev, &smpro_regmap_bus, &i2c->dev, config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ ret = regmap_read(regmap, MANUFACTURER_ID_REG, &val);
+ if (ret)
+ return ret;
+
+ if (val != AMPERE_MANUFACTURER_ID)
+ return -ENODEV;
+
+ return devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
+ smpro_devs, ARRAY_SIZE(smpro_devs), NULL, 0, NULL);
+}
+
+static const struct of_device_id smpro_core_of_match[] = {
+ { .compatible = "ampere,smpro", .data = &smpro_regmap_config },
+ {}
+};
+MODULE_DEVICE_TABLE(of, smpro_core_of_match);
+
+static struct i2c_driver smpro_core_driver = {
+ .probe_new = smpro_core_probe,
+ .driver = {
+ .name = "smpro-core",
+ .of_match_table = smpro_core_of_match,
+ },
+};
+module_i2c_driver(smpro_core_driver);
+
+MODULE_AUTHOR("Quan Nguyen <quan@os.amperecomputing.com>");
+MODULE_DESCRIPTION("SMPRO CORE - I2C driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/sprd-sc27xx-spi.c b/drivers/mfd/sprd-sc27xx-spi.c
index d05a47c5187f..d21f32cc784d 100644
--- a/drivers/mfd/sprd-sc27xx-spi.c
+++ b/drivers/mfd/sprd-sc27xx-spi.c
@@ -181,11 +181,10 @@ static int sprd_pmic_probe(struct spi_device *spi)
ddata->irq_chip.name = dev_name(&spi->dev);
ddata->irq_chip.status_base =
pdata->irq_base + SPRD_PMIC_INT_MASK_STATUS;
- ddata->irq_chip.mask_base = pdata->irq_base + SPRD_PMIC_INT_EN;
+ ddata->irq_chip.unmask_base = pdata->irq_base + SPRD_PMIC_INT_EN;
ddata->irq_chip.ack_base = 0;
ddata->irq_chip.num_regs = 1;
ddata->irq_chip.num_irqs = pdata->num_irqs;
- ddata->irq_chip.mask_invert = true;
ddata->irqs = devm_kcalloc(&spi->dev,
pdata->num_irqs, sizeof(struct regmap_irq),
@@ -215,7 +214,6 @@ static int sprd_pmic_probe(struct spi_device *spi)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int sprd_pmic_suspend(struct device *dev)
{
struct sprd_pmic *ddata = dev_get_drvdata(dev);
@@ -235,9 +233,9 @@ static int sprd_pmic_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(sprd_pmic_pm_ops, sprd_pmic_suspend, sprd_pmic_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(sprd_pmic_pm_ops,
+ sprd_pmic_suspend, sprd_pmic_resume);
static const struct of_device_id sprd_pmic_match[] = {
{ .compatible = "sprd,sc2730", .data = &sc2730_data },
@@ -257,7 +255,7 @@ static struct spi_driver sprd_pmic_driver = {
.driver = {
.name = "sc27xx-pmic",
.of_match_table = sprd_pmic_match,
- .pm = &sprd_pmic_pm_ops,
+ .pm = pm_sleep_ptr(&sprd_pmic_pm_ops),
},
.probe = sprd_pmic_probe,
.id_table = sprd_pmic_spi_ids,
diff --git a/drivers/mfd/stm32-lptimer.c b/drivers/mfd/stm32-lptimer.c
index 746e51a17cc8..fa322f4412c8 100644
--- a/drivers/mfd/stm32-lptimer.c
+++ b/drivers/mfd/stm32-lptimer.c
@@ -52,7 +52,6 @@ static int stm32_lptimer_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct stm32_lptimer *ddata;
- struct resource *res;
void __iomem *mmio;
int ret;
@@ -60,8 +59,7 @@ static int stm32_lptimer_probe(struct platform_device *pdev)
if (!ddata)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- mmio = devm_ioremap_resource(dev, res);
+ mmio = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
if (IS_ERR(mmio))
return PTR_ERR(mmio);
diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c
index 5dd7d9688459..e281971ba54e 100644
--- a/drivers/mfd/stmfx.c
+++ b/drivers/mfd/stmfx.c
@@ -410,8 +410,7 @@ static void stmfx_chip_exit(struct i2c_client *client)
}
}
-static int stmfx_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int stmfx_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct stmfx *stmfx;
@@ -474,7 +473,6 @@ static void stmfx_remove(struct i2c_client *client)
stmfx_chip_exit(client);
}
-#ifdef CONFIG_PM_SLEEP
static int stmfx_suspend(struct device *dev)
{
struct stmfx *stmfx = dev_get_drvdata(dev);
@@ -540,9 +538,8 @@ static int stmfx_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(stmfx_dev_pm_ops, stmfx_suspend, stmfx_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(stmfx_dev_pm_ops, stmfx_suspend, stmfx_resume);
static const struct of_device_id stmfx_of_match[] = {
{ .compatible = "st,stmfx-0300", },
@@ -554,9 +551,9 @@ static struct i2c_driver stmfx_driver = {
.driver = {
.name = "stmfx-core",
.of_match_table = stmfx_of_match,
- .pm = &stmfx_dev_pm_ops,
+ .pm = pm_sleep_ptr(&stmfx_dev_pm_ops),
},
- .probe = stmfx_probe,
+ .probe_new = stmfx_probe,
.remove = stmfx_remove,
};
module_i2c_driver(stmfx_driver);
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index 4d55494a97c4..d4944fc1feb1 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -67,8 +67,9 @@ static const struct of_device_id stmpe_of_match[] = {
MODULE_DEVICE_TABLE(of, stmpe_of_match);
static int
-stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+stmpe_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
enum stmpe_partnum partnum;
const struct of_device_id *of_id;
@@ -114,12 +115,10 @@ MODULE_DEVICE_TABLE(i2c, stmpe_i2c_id);
static struct i2c_driver stmpe_i2c_driver = {
.driver = {
.name = "stmpe-i2c",
-#ifdef CONFIG_PM
- .pm = &stmpe_dev_pm_ops,
-#endif
+ .pm = pm_sleep_ptr(&stmpe_dev_pm_ops),
.of_match_table = stmpe_of_match,
},
- .probe = stmpe_i2c_probe,
+ .probe_new = stmpe_i2c_probe,
.remove = stmpe_i2c_remove,
.id_table = stmpe_i2c_id,
};
diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c
index ad8055a0e286..e9cbf33502b3 100644
--- a/drivers/mfd/stmpe-spi.c
+++ b/drivers/mfd/stmpe-spi.c
@@ -135,9 +135,7 @@ static struct spi_driver stmpe_spi_driver = {
.driver = {
.name = "stmpe-spi",
.of_match_table = of_match_ptr(stmpe_spi_of_match),
-#ifdef CONFIG_PM
- .pm = &stmpe_dev_pm_ops,
-#endif
+ .pm = pm_sleep_ptr(&stmpe_dev_pm_ops),
},
.probe = stmpe_spi_probe,
.remove = stmpe_spi_remove,
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 0c4f74197d3e..c304d20bb988 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -1495,7 +1495,6 @@ void stmpe_remove(struct stmpe *stmpe)
mfd_remove_devices(stmpe->dev);
}
-#ifdef CONFIG_PM
static int stmpe_suspend(struct device *dev)
{
struct stmpe *stmpe = dev_get_drvdata(dev);
@@ -1516,8 +1515,5 @@ static int stmpe_resume(struct device *dev)
return 0;
}
-const struct dev_pm_ops stmpe_dev_pm_ops = {
- .suspend = stmpe_suspend,
- .resume = stmpe_resume,
-};
-#endif
+EXPORT_GPL_SIMPLE_DEV_PM_OPS(stmpe_dev_pm_ops,
+ stmpe_suspend, stmpe_resume);
diff --git a/drivers/mfd/stpmic1.c b/drivers/mfd/stpmic1.c
index eb3da558c3fb..8db1530d9bac 100644
--- a/drivers/mfd/stpmic1.c
+++ b/drivers/mfd/stpmic1.c
@@ -108,16 +108,16 @@ static const struct regmap_irq stpmic1_irqs[] = {
static const struct regmap_irq_chip stpmic1_regmap_irq_chip = {
.name = "pmic_irq",
.status_base = INT_PENDING_R1,
- .mask_base = INT_CLEAR_MASK_R1,
- .unmask_base = INT_SET_MASK_R1,
+ .mask_base = INT_SET_MASK_R1,
+ .unmask_base = INT_CLEAR_MASK_R1,
+ .mask_unmask_non_inverted = true,
.ack_base = INT_CLEAR_R1,
.num_regs = STPMIC1_PMIC_NUM_IRQ_REGS,
.irqs = stpmic1_irqs,
.num_irqs = ARRAY_SIZE(stpmic1_irqs),
};
-static int stpmic1_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int stpmic1_probe(struct i2c_client *i2c)
{
struct stpmic1 *ddata;
struct device *dev = &i2c->dev;
@@ -162,7 +162,6 @@ static int stpmic1_probe(struct i2c_client *i2c,
return devm_of_platform_populate(dev);
}
-#ifdef CONFIG_PM_SLEEP
static int stpmic1_suspend(struct device *dev)
{
struct i2c_client *i2c = to_i2c_client(dev);
@@ -187,9 +186,8 @@ static int stpmic1_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(stpmic1_pm, stpmic1_suspend, stpmic1_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(stpmic1_pm, stpmic1_suspend, stpmic1_resume);
static const struct of_device_id stpmic1_of_match[] = {
{ .compatible = "st,stpmic1", },
@@ -201,9 +199,9 @@ static struct i2c_driver stpmic1_driver = {
.driver = {
.name = "stpmic1",
.of_match_table = of_match_ptr(stpmic1_of_match),
- .pm = &stpmic1_pm,
+ .pm = pm_sleep_ptr(&stpmic1_pm),
},
- .probe = stpmic1_probe,
+ .probe_new = stpmic1_probe,
};
module_i2c_driver(stpmic1_driver);
diff --git a/drivers/mfd/stw481x.c b/drivers/mfd/stw481x.c
index 7478f03ccbae..2a8fc9d1c806 100644
--- a/drivers/mfd/stw481x.c
+++ b/drivers/mfd/stw481x.c
@@ -173,8 +173,7 @@ static const struct regmap_config stw481x_regmap_config = {
.val_bits = 8,
};
-static int stw481x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int stw481x_probe(struct i2c_client *client)
{
struct stw481x *stw481x;
int ret;
@@ -240,7 +239,7 @@ static struct i2c_driver stw481x_driver = {
.name = "stw481x",
.of_match_table = stw481x_match,
},
- .probe = stw481x_probe,
+ .probe_new = stw481x_probe,
.id_table = stw481x_id,
};
diff --git a/drivers/mfd/sun4i-gpadc.c b/drivers/mfd/sun4i-gpadc.c
index cfe14d9bf6dc..edc180d83a4b 100644
--- a/drivers/mfd/sun4i-gpadc.c
+++ b/drivers/mfd/sun4i-gpadc.c
@@ -34,9 +34,8 @@ static const struct regmap_irq_chip sun4i_gpadc_regmap_irq_chip = {
.name = "sun4i_gpadc_irq_chip",
.status_base = SUN4I_GPADC_INT_FIFOS,
.ack_base = SUN4I_GPADC_INT_FIFOS,
- .mask_base = SUN4I_GPADC_INT_FIFOC,
+ .unmask_base = SUN4I_GPADC_INT_FIFOC,
.init_ack_masked = true,
- .mask_invert = true,
.irqs = sun4i_gpadc_regmap_irq,
.num_irqs = ARRAY_SIZE(sun4i_gpadc_regmap_irq),
.num_regs = 1,
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 663ffd4b8570..1d9d1d38d068 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -257,7 +257,6 @@ static void t7l66xb_detach_irq(struct platform_device *dev)
/*--------------------------------------------------------------------------*/
-#ifdef CONFIG_PM
static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state)
{
struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
@@ -288,10 +287,6 @@ static int t7l66xb_resume(struct platform_device *dev)
return 0;
}
-#else
-#define t7l66xb_suspend NULL
-#define t7l66xb_resume NULL
-#endif
/*--------------------------------------------------------------------------*/
@@ -416,8 +411,8 @@ static struct platform_driver t7l66xb_platform_driver = {
.driver = {
.name = "t7l66xb",
},
- .suspend = t7l66xb_suspend,
- .resume = t7l66xb_resume,
+ .suspend = pm_sleep_ptr(t7l66xb_suspend),
+ .resume = pm_sleep_ptr(t7l66xb_resume),
.probe = t7l66xb_probe,
.remove = t7l66xb_remove,
};
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index d5d0ec117acb..1f6e0d682cd9 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -352,9 +352,9 @@ tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
return pdata;
}
-static int tc3589x_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int tc3589x_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct device_node *np = i2c->dev.of_node;
struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct tc3589x *tc3589x;
@@ -436,7 +436,6 @@ static void tc3589x_remove(struct i2c_client *client)
mfd_remove_devices(tc3589x->dev);
}
-#ifdef CONFIG_PM_SLEEP
static int tc3589x_suspend(struct device *dev)
{
struct tc3589x *tc3589x = dev_get_drvdata(dev);
@@ -464,9 +463,9 @@ static int tc3589x_resume(struct device *dev)
return ret;
}
-#endif
-static SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, tc3589x_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops,
+ tc3589x_suspend, tc3589x_resume);
static const struct i2c_device_id tc3589x_id[] = {
{ "tc35890", TC3589X_TC35890 },
@@ -483,10 +482,10 @@ MODULE_DEVICE_TABLE(i2c, tc3589x_id);
static struct i2c_driver tc3589x_driver = {
.driver = {
.name = "tc3589x",
- .pm = &tc3589x_dev_pm_ops,
+ .pm = pm_sleep_ptr(&tc3589x_dev_pm_ops),
.of_match_table = of_match_ptr(tc3589x_match),
},
- .probe = tc3589x_probe,
+ .probe_new = tc3589x_probe,
.remove = tc3589x_remove,
.id_table = tc3589x_id,
};
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index e846e4d26b6e..5392da6ba7b0 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -40,7 +40,6 @@ static const struct resource tc6387xb_mmc_resources[] = {
/*--------------------------------------------------------------------------*/
-#ifdef CONFIG_PM
static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
{
struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
@@ -67,10 +66,6 @@ static int tc6387xb_resume(struct platform_device *dev)
return 0;
}
-#else
-#define tc6387xb_suspend NULL
-#define tc6387xb_resume NULL
-#endif
/*--------------------------------------------------------------------------*/
@@ -220,8 +215,8 @@ static struct platform_driver tc6387xb_platform_driver = {
},
.probe = tc6387xb_probe,
.remove = tc6387xb_remove,
- .suspend = tc6387xb_suspend,
- .resume = tc6387xb_resume,
+ .suspend = pm_sleep_ptr(tc6387xb_suspend),
+ .resume = pm_sleep_ptr(tc6387xb_resume),
};
module_platform_driver(tc6387xb_platform_driver);
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index aa903a31dd43..997bb8b5881d 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -813,7 +813,6 @@ static int tc6393xb_remove(struct platform_device *dev)
return 0;
}
-#ifdef CONFIG_PM
static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
{
struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
@@ -876,16 +875,12 @@ static int tc6393xb_resume(struct platform_device *dev)
return 0;
}
-#else
-#define tc6393xb_suspend NULL
-#define tc6393xb_resume NULL
-#endif
static struct platform_driver tc6393xb_driver = {
.probe = tc6393xb_probe,
.remove = tc6393xb_remove,
- .suspend = tc6393xb_suspend,
- .resume = tc6393xb_resume,
+ .suspend = pm_sleep_ptr(tc6393xb_suspend),
+ .resume = pm_sleep_ptr(tc6393xb_resume),
.driver = {
.name = "tc6393xb",
diff --git a/drivers/mfd/ti-lmu.c b/drivers/mfd/ti-lmu.c
index fd6e8c417baa..9921320be255 100644
--- a/drivers/mfd/ti-lmu.c
+++ b/drivers/mfd/ti-lmu.c
@@ -133,8 +133,9 @@ TI_LMU_DATA(lm3633, LM3633_MAX_REG);
TI_LMU_DATA(lm3695, LM3695_MAX_REG);
TI_LMU_DATA(lm36274, LM36274_MAX_REG);
-static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+static int ti_lmu_probe(struct i2c_client *cl)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(cl);
struct device *dev = &cl->dev;
const struct ti_lmu_data *data;
struct regmap_config regmap_cfg;
@@ -216,7 +217,7 @@ static const struct i2c_device_id ti_lmu_ids[] = {
MODULE_DEVICE_TABLE(i2c, ti_lmu_ids);
static struct i2c_driver ti_lmu_driver = {
- .probe = ti_lmu_probe,
+ .probe_new = ti_lmu_probe,
.driver = {
.name = "ti-lmu",
.of_match_table = ti_lmu_of_match,
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index 9393ee60a656..07e5aa10a146 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/msi.h>
#include <linux/mfd/core.h>
#include <linux/slab.h>
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c
index b360568ea675..a66cb911998d 100644
--- a/drivers/mfd/tps6105x.c
+++ b/drivers/mfd/tps6105x.c
@@ -117,8 +117,7 @@ static struct tps6105x_platform_data *tps6105x_parse_dt(struct device *dev)
return pdata;
}
-static int tps6105x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tps6105x_probe(struct i2c_client *client)
{
struct tps6105x *tps6105x;
struct tps6105x_platform_data *pdata;
@@ -210,7 +209,7 @@ static struct i2c_driver tps6105x_driver = {
.name = "tps6105x",
.of_match_table = tps6105x_of_match,
},
- .probe = tps6105x_probe,
+ .probe_new = tps6105x_probe,
.remove = tps6105x_remove,
.id_table = tps6105x_id,
};
diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c
index c2afa2e69f42..fb733288cca3 100644
--- a/drivers/mfd/tps65010.c
+++ b/drivers/mfd/tps65010.c
@@ -519,9 +519,9 @@ static void tps65010_remove(struct i2c_client *client)
the_tps = NULL;
}
-static int tps65010_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tps65010_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct tps65010 *tps;
int status;
struct tps65010_board *board = dev_get_platdata(&client->dev);
@@ -668,7 +668,7 @@ static struct i2c_driver tps65010_driver = {
.driver = {
.name = "tps65010",
},
- .probe = tps65010_probe,
+ .probe_new = tps65010_probe,
.remove = tps65010_remove,
.id_table = tps65010_id,
};
diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c
index 1f308c4e3694..500b594de316 100644
--- a/drivers/mfd/tps6507x.c
+++ b/drivers/mfd/tps6507x.c
@@ -84,8 +84,7 @@ static int tps6507x_i2c_write_device(struct tps6507x_dev *tps6507x, char reg,
return 0;
}
-static int tps6507x_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int tps6507x_i2c_probe(struct i2c_client *i2c)
{
struct tps6507x_dev *tps6507x;
@@ -123,7 +122,7 @@ static struct i2c_driver tps6507x_i2c_driver = {
.name = "tps6507x",
.of_match_table = of_match_ptr(tps6507x_of_match),
},
- .probe = tps6507x_i2c_probe,
+ .probe_new = tps6507x_i2c_probe,
.id_table = tps6507x_i2c_id,
};
diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
index 81a7360a87bb..9494c1d71b86 100644
--- a/drivers/mfd/tps65086.c
+++ b/drivers/mfd/tps65086.c
@@ -61,8 +61,7 @@ static const struct of_device_id tps65086_of_match_table[] = {
};
MODULE_DEVICE_TABLE(of, tps65086_of_match_table);
-static int tps65086_probe(struct i2c_client *client,
- const struct i2c_device_id *ids)
+static int tps65086_probe(struct i2c_client *client)
{
struct tps65086 *tps;
unsigned int version;
@@ -130,7 +129,7 @@ static struct i2c_driver tps65086_driver = {
.name = "tps65086",
.of_match_table = tps65086_of_match_table,
},
- .probe = tps65086_probe,
+ .probe_new = tps65086_probe,
.remove = tps65086_remove,
.id_table = tps65086_id_table,
};
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index bd6235308c6b..af718a9c58b3 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -127,8 +127,7 @@ static struct regmap_irq_chip tps65090_irq_chip = {
.num_irqs = ARRAY_SIZE(tps65090_irqs),
.num_regs = NUM_INT_REG,
.status_base = TPS65090_REG_INTR_STS,
- .mask_base = TPS65090_REG_INTR_MASK,
- .mask_invert = true,
+ .unmask_base = TPS65090_REG_INTR_MASK,
};
static bool is_volatile_reg(struct device *dev, unsigned int reg)
@@ -164,8 +163,7 @@ static const struct of_device_id tps65090_of_match[] = {
};
#endif
-static int tps65090_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tps65090_i2c_probe(struct i2c_client *client)
{
struct tps65090_platform_data *pdata = dev_get_platdata(&client->dev);
int irq_base = 0;
@@ -238,7 +236,7 @@ static struct i2c_driver tps65090_driver = {
.suppress_bind_attrs = true,
.of_match_table = of_match_ptr(tps65090_of_match),
},
- .probe = tps65090_i2c_probe,
+ .probe_new = tps65090_i2c_probe,
.id_table = tps65090_id_table,
};
diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c
index 49bb8fd168f8..ea69dcef91ec 100644
--- a/drivers/mfd/tps65218.c
+++ b/drivers/mfd/tps65218.c
@@ -280,8 +280,7 @@ static int tps65218_voltage_set_uvlo(struct tps65218 *tps)
return 0;
}
-static int tps65218_probe(struct i2c_client *client,
- const struct i2c_device_id *ids)
+static int tps65218_probe(struct i2c_client *client)
{
struct tps65218 *tps;
int ret;
@@ -348,7 +347,7 @@ static struct i2c_driver tps65218_driver = {
.name = "tps65218",
.of_match_table = of_tps65218_match_table,
},
- .probe = tps65218_probe,
+ .probe_new = tps65218_probe,
.id_table = tps65218_id_table,
};
diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
new file mode 100644
index 000000000000..0e402fda206b
--- /dev/null
+++ b/drivers/mfd/tps65219.c
@@ -0,0 +1,299 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Driver for TPS65219 Integrated Power Management Integrated Chips (PMIC)
+//
+// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+
+#include <linux/i2c.h>
+#include <linux/reboot.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/tps65219.h>
+
+static int tps65219_warm_reset(struct tps65219 *tps)
+{
+ return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
+ TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK,
+ TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK);
+}
+
+static int tps65219_cold_reset(struct tps65219 *tps)
+{
+ return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
+ TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK,
+ TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK);
+}
+
+static int tps65219_restart(struct notifier_block *this,
+ unsigned long reboot_mode, void *cmd)
+{
+ struct tps65219 *tps;
+
+ tps = container_of(this, struct tps65219, nb);
+
+ if (reboot_mode == REBOOT_WARM)
+ tps65219_warm_reset(tps);
+ else
+ tps65219_cold_reset(tps);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block pmic_rst_restart_nb = {
+ .notifier_call = tps65219_restart,
+ .priority = 200,
+};
+
+static const struct resource tps65219_pwrbutton_resources[] = {
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_FALLING_EDGE_DETECT, "falling"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_RISING_EDGE_DETECT, "rising"),
+};
+
+static const struct resource tps65219_regulator_resources[] = {
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_SCG, "LDO3_SCG"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_OC, "LDO3_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_UV, "LDO3_UV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_SCG, "LDO4_SCG"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_OC, "LDO4_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_UV, "LDO4_UV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_SCG, "LDO1_SCG"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_OC, "LDO1_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_UV, "LDO1_UV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_SCG, "LDO2_SCG"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_OC, "LDO2_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_UV, "LDO2_UV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV, "LDO2_RV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV, "LDO3_RV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV, "LDO4_RV"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV_SD, "LDO1_RV_SD"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV_SD, "LDO2_RV_SD"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV_SD, "LDO3_RV_SD"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV_SD, "LDO4_RV_SD"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_WARM, "SENSOR_3_WARM"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_HOT, "SENSOR_3_HOT"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
+ DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
+};
+
+static const struct mfd_cell tps65219_cells[] = {
+ {
+ .name = "tps65219-regulator",
+ .resources = tps65219_regulator_resources,
+ .num_resources = ARRAY_SIZE(tps65219_regulator_resources),
+ },
+ { .name = "tps65219-gpios", },
+};
+
+static const struct mfd_cell tps65219_pwrbutton_cell = {
+ .name = "tps65219-pwrbutton",
+ .resources = tps65219_pwrbutton_resources,
+ .num_resources = ARRAY_SIZE(tps65219_pwrbutton_resources),
+};
+
+static const struct regmap_config tps65219_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = TPS65219_REG_FACTORY_CONFIG_2,
+};
+
+/*
+ * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can
+ * access corect sub-IRQ registers based on bits that are set in main IRQ
+ * register.
+ */
+/* Timeout Residual Voltage Shutdown */
+static unsigned int bit0_offsets[] = { TPS65219_REG_INT_TO_RV_POS };
+static unsigned int bit1_offsets[] = { TPS65219_REG_INT_RV_POS }; /* Residual Voltage */
+static unsigned int bit2_offsets[] = { TPS65219_REG_INT_SYS_POS }; /* System */
+static unsigned int bit3_offsets[] = { TPS65219_REG_INT_BUCK_1_2_POS }; /* Buck 1-2 */
+static unsigned int bit4_offsets[] = { TPS65219_REG_INT_BUCK_3_POS }; /* Buck 3 */
+static unsigned int bit5_offsets[] = { TPS65219_REG_INT_LDO_1_2_POS }; /* LDO 1-2 */
+static unsigned int bit6_offsets[] = { TPS65219_REG_INT_LDO_3_4_POS }; /* LDO 3-4 */
+static unsigned int bit7_offsets[] = { TPS65219_REG_INT_PB_POS }; /* Power Button */
+
+static struct regmap_irq_sub_irq_map tps65219_sub_irq_offsets[] = {
+ REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
+ REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
+ REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
+ REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
+ REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
+ REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
+ REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
+ REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
+};
+
+#define TPS65219_REGMAP_IRQ_REG(int_name, register_position) \
+ REGMAP_IRQ_REG(int_name, register_position, int_name##_MASK)
+
+static struct regmap_irq tps65219_irqs[] = {
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_SCG, TPS65219_REG_INT_LDO_3_4_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_OC, TPS65219_REG_INT_LDO_3_4_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_UV, TPS65219_REG_INT_LDO_3_4_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_SCG, TPS65219_REG_INT_LDO_3_4_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_OC, TPS65219_REG_INT_LDO_3_4_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_UV, TPS65219_REG_INT_LDO_3_4_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_SCG, TPS65219_REG_INT_LDO_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_OC, TPS65219_REG_INT_LDO_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_UV, TPS65219_REG_INT_LDO_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_SCG, TPS65219_REG_INT_LDO_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_OC, TPS65219_REG_INT_LDO_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_UV, TPS65219_REG_INT_LDO_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65219_REG_INT_BUCK_3_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65219_REG_INT_BUCK_3_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65219_REG_INT_BUCK_3_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65219_REG_INT_BUCK_3_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65219_REG_INT_BUCK_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65219_REG_INT_BUCK_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65219_REG_INT_BUCK_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65219_REG_INT_BUCK_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65219_REG_INT_BUCK_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65219_REG_INT_BUCK_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65219_REG_INT_BUCK_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65219_REG_INT_BUCK_1_2_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_WARM, TPS65219_REG_INT_SYS_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65219_REG_INT_SYS_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65219_REG_INT_SYS_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65219_REG_INT_SYS_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_HOT, TPS65219_REG_INT_SYS_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65219_REG_INT_SYS_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65219_REG_INT_SYS_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65219_REG_INT_SYS_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65219_REG_INT_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65219_REG_INT_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65219_REG_INT_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65219_REG_INT_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV, TPS65219_REG_INT_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV, TPS65219_REG_INT_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV, TPS65219_REG_INT_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65219_REG_INT_TO_RV_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
+ TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
+};
+
+static struct regmap_irq_chip tps65219_irq_chip = {
+ .name = "tps65219_irq",
+ .main_status = TPS65219_REG_INT_SOURCE,
+ .num_main_regs = 1,
+ .num_main_status_bits = 8,
+ .irqs = tps65219_irqs,
+ .num_irqs = ARRAY_SIZE(tps65219_irqs),
+ .status_base = TPS65219_REG_INT_LDO_3_4,
+ .ack_base = TPS65219_REG_INT_LDO_3_4,
+ .clear_ack = 1,
+ .num_regs = 8,
+ .sub_reg_offsets = tps65219_sub_irq_offsets,
+};
+
+static int tps65219_probe(struct i2c_client *client)
+{
+ struct tps65219 *tps;
+ unsigned int chipid;
+ bool pwr_button;
+ int ret;
+
+ tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+ if (!tps)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, tps);
+
+ tps->dev = &client->dev;
+
+ tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
+ if (IS_ERR(tps->regmap)) {
+ ret = PTR_ERR(tps->regmap);
+ dev_err(tps->dev, "Failed to allocate register map: %d\n", ret);
+ return ret;
+ }
+
+ ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, client->irq,
+ IRQF_ONESHOT, 0, &tps65219_irq_chip,
+ &tps->irq_data);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
+ if (ret) {
+ dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
+ return ret;
+ }
+
+ ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO,
+ tps65219_cells, ARRAY_SIZE(tps65219_cells),
+ NULL, 0, regmap_irq_get_domain(tps->irq_data));
+ if (ret) {
+ dev_err(tps->dev, "Failed to add child devices: %d\n", ret);
+ return ret;
+ }
+
+ pwr_button = of_property_read_bool(tps->dev->of_node, "ti,power-button");
+ if (pwr_button) {
+ ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO,
+ &tps65219_pwrbutton_cell, 1, NULL, 0,
+ regmap_irq_get_domain(tps->irq_data));
+ if (ret) {
+ dev_err(tps->dev, "Failed to add power-button: %d\n", ret);
+ return ret;
+ }
+ }
+
+ tps->nb = pmic_rst_restart_nb;
+ ret = register_restart_handler(&tps->nb);
+ if (ret) {
+ dev_err(tps->dev, "cannot register restart handler, %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id of_tps65219_match_table[] = {
+ { .compatible = "ti,tps65219", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, of_tps65219_match_table);
+
+static struct i2c_driver tps65219_driver = {
+ .driver = {
+ .name = "tps65219",
+ .of_match_table = of_tps65219_match_table,
+ },
+ .probe_new = tps65219_probe,
+};
+module_i2c_driver(tps65219_driver);
+
+MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
+MODULE_DESCRIPTION("TPS65219 power management IC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index fb340da64bbc..2d947f3f606a 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -269,15 +269,11 @@ static void tps6586x_irq_sync_unlock(struct irq_data *data)
mutex_unlock(&tps6586x->irq_lock);
}
-#ifdef CONFIG_PM_SLEEP
static int tps6586x_irq_set_wake(struct irq_data *irq_data, unsigned int on)
{
struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
return irq_set_irq_wake(tps6586x->irq, on);
}
-#else
-#define tps6586x_irq_set_wake NULL
-#endif
static struct irq_chip tps6586x_irq_chip = {
.name = "tps6586x",
@@ -285,7 +281,7 @@ static struct irq_chip tps6586x_irq_chip = {
.irq_bus_sync_unlock = tps6586x_irq_sync_unlock,
.irq_disable = tps6586x_irq_disable,
.irq_enable = tps6586x_irq_enable,
- .irq_set_wake = tps6586x_irq_set_wake,
+ .irq_set_wake = pm_sleep_ptr(tps6586x_irq_set_wake),
};
static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq,
@@ -499,8 +495,7 @@ static void tps6586x_print_version(struct i2c_client *client, int version)
dev_info(&client->dev, "Found %s, VERSIONCRC is %02x\n", name, version);
}
-static int tps6586x_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tps6586x_i2c_probe(struct i2c_client *client)
{
struct tps6586x_platform_data *pdata = dev_get_platdata(&client->dev);
struct tps6586x *tps6586x;
@@ -624,7 +619,7 @@ static struct i2c_driver tps6586x_driver = {
.of_match_table = of_match_ptr(tps6586x_of_match),
.pm = &tps6586x_pm_ops,
},
- .probe = tps6586x_i2c_probe,
+ .probe_new = tps6586x_i2c_probe,
.remove = tps6586x_i2c_remove,
.id_table = tps6586x_id_table,
};
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index 67e2707af4bc..821c0277a2ed 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -441,9 +441,9 @@ static void tps65910_power_off(void)
DEVCTRL_DEV_OFF_MASK);
}
-static int tps65910_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int tps65910_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct tps65910 *tps65910;
struct tps65910_board *pmic_plat_data;
struct tps65910_board *of_pmic_plat_data = NULL;
@@ -535,7 +535,7 @@ static struct i2c_driver tps65910_i2c_driver = {
.name = "tps65910",
.of_match_table = of_match_ptr(tps65910_of_match),
},
- .probe = tps65910_i2c_probe,
+ .probe_new = tps65910_i2c_probe,
.id_table = tps65910_i2c_id,
};
diff --git a/drivers/mfd/tps65912-i2c.c b/drivers/mfd/tps65912-i2c.c
index 7e2b19efe867..1bf945966bf7 100644
--- a/drivers/mfd/tps65912-i2c.c
+++ b/drivers/mfd/tps65912-i2c.c
@@ -21,8 +21,7 @@ static const struct of_device_id tps65912_i2c_of_match_table[] = {
};
MODULE_DEVICE_TABLE(of, tps65912_i2c_of_match_table);
-static int tps65912_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *ids)
+static int tps65912_i2c_probe(struct i2c_client *client)
{
struct tps65912 *tps;
@@ -61,7 +60,7 @@ static struct i2c_driver tps65912_i2c_driver = {
.name = "tps65912",
.of_match_table = tps65912_i2c_of_match_table,
},
- .probe = tps65912_i2c_probe,
+ .probe_new = tps65912_i2c_probe,
.remove = tps65912_i2c_remove,
.id_table = tps65912_i2c_id_table,
};
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index f6b4b9d94bbd..62be2326c9b2 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -754,8 +754,9 @@ static struct of_dev_auxdata twl_auxdata_lookup[] = {
/* NOTE: This driver only handles a single twl4030/tps659x0 chip */
static int
-twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
+twl_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device_node *node = client->dev.of_node;
struct platform_device *pdev;
const struct regmap_config *twl_regmap_config;
@@ -955,7 +956,7 @@ static struct i2c_driver twl_driver = {
.driver.name = DRIVER_NAME,
.driver.pm = &twl_dev_pm_ops,
.id_table = twl_ids,
- .probe = twl_probe,
+ .probe_new = twl_probe,
.remove = twl_remove,
};
builtin_i2c_driver(twl_driver);
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c
index f429b8f00db6..fc97fa5a2d0c 100644
--- a/drivers/mfd/twl6040.c
+++ b/drivers/mfd/twl6040.c
@@ -17,9 +17,8 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_irq.h>
-#include <linux/of_gpio.h>
#include <linux/of_platform.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
@@ -251,7 +250,7 @@ static int twl6040_power_up_automatic(struct twl6040 *twl6040)
{
int time_left;
- gpio_set_value(twl6040->audpwron, 1);
+ gpiod_set_value_cansleep(twl6040->audpwron, 1);
time_left = wait_for_completion_timeout(&twl6040->ready,
msecs_to_jiffies(144));
@@ -262,7 +261,7 @@ static int twl6040_power_up_automatic(struct twl6040 *twl6040)
intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
if (!(intid & TWL6040_READYINT)) {
dev_err(twl6040->dev, "automatic power-up failed\n");
- gpio_set_value(twl6040->audpwron, 0);
+ gpiod_set_value_cansleep(twl6040->audpwron, 0);
return -ETIMEDOUT;
}
}
@@ -290,7 +289,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
/* Allow writes to the chip */
regcache_cache_only(twl6040->regmap, false);
- if (gpio_is_valid(twl6040->audpwron)) {
+ if (twl6040->audpwron) {
/* use automatic power-up sequence */
ret = twl6040_power_up_automatic(twl6040);
if (ret) {
@@ -337,9 +336,9 @@ int twl6040_power(struct twl6040 *twl6040, int on)
if (--twl6040->power_count)
goto out;
- if (gpio_is_valid(twl6040->audpwron)) {
+ if (twl6040->audpwron) {
/* use AUDPWRON line */
- gpio_set_value(twl6040->audpwron, 0);
+ gpiod_set_value_cansleep(twl6040->audpwron, 0);
/* power-down sequence latency */
usleep_range(500, 700);
@@ -633,8 +632,7 @@ static struct regmap_irq_chip twl6040_irq_chip = {
.mask_base = TWL6040_REG_INTMR,
};
-static int twl6040_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int twl6040_probe(struct i2c_client *client)
{
struct device_node *node = client->dev.of_node;
struct twl6040 *twl6040;
@@ -712,18 +710,16 @@ static int twl6040_probe(struct i2c_client *client,
}
/* ERRATA: Automatic power-up is not possible in ES1.0 */
- if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
- twl6040->audpwron = of_get_named_gpio(node,
- "ti,audpwron-gpio", 0);
- else
- twl6040->audpwron = -EINVAL;
-
- if (gpio_is_valid(twl6040->audpwron)) {
- ret = devm_gpio_request_one(&client->dev, twl6040->audpwron,
- GPIOF_OUT_INIT_LOW, "audpwron");
+ if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) {
+ twl6040->audpwron = devm_gpiod_get_optional(&client->dev,
+ "ti,audpwron",
+ GPIOD_OUT_LOW);
+ ret = PTR_ERR_OR_ZERO(twl6040->audpwron);
if (ret)
goto gpio_err;
+ gpiod_set_consumer_name(twl6040->audpwron, "audpwron");
+
/* Clear any pending interrupt */
twl6040_reg_read(twl6040, TWL6040_REG_INTID);
}
@@ -833,7 +829,7 @@ static struct i2c_driver twl6040_driver = {
.driver = {
.name = "twl6040",
},
- .probe = twl6040_probe,
+ .probe_new = twl6040_probe,
.remove = twl6040_remove,
.id_table = twl6040_i2c_id,
};
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index b690796d24d4..fc4d4c844a81 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -660,7 +660,6 @@ void ucb1x00_unregister_driver(struct ucb1x00_driver *drv)
mutex_unlock(&ucb1x00_mutex);
}
-#ifdef CONFIG_PM_SLEEP
static int ucb1x00_suspend(struct device *dev)
{
struct ucb1x00_plat_data *pdata = dev_get_platdata(dev);
@@ -728,15 +727,15 @@ static int ucb1x00_resume(struct device *dev)
mutex_unlock(&ucb1x00_mutex);
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(ucb1x00_pm_ops, ucb1x00_suspend, ucb1x00_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(ucb1x00_pm_ops,
+ ucb1x00_suspend, ucb1x00_resume);
static struct mcp_driver ucb1x00_driver = {
.drv = {
.name = "ucb1x00",
.owner = THIS_MODULE,
- .pm = &ucb1x00_pm_ops,
+ .pm = pm_sleep_ptr(&ucb1x00_pm_ops),
},
.probe = ucb1x00_probe,
.remove = ucb1x00_remove,
diff --git a/drivers/mfd/wcd934x.c b/drivers/mfd/wcd934x.c
index 68e2fa2fda99..07e884087f2c 100644
--- a/drivers/mfd/wcd934x.c
+++ b/drivers/mfd/wcd934x.c
@@ -55,17 +55,22 @@ static const struct regmap_irq wcd934x_irqs[] = {
WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_SOUNDWIRE, 2, BIT(4)),
};
+static const unsigned int wcd934x_config_regs[] = {
+ WCD934X_INTR_LEVEL0,
+};
+
static const struct regmap_irq_chip wcd934x_regmap_irq_chip = {
.name = "wcd934x_irq",
.status_base = WCD934X_INTR_PIN1_STATUS0,
.mask_base = WCD934X_INTR_PIN1_MASK0,
.ack_base = WCD934X_INTR_PIN1_CLEAR0,
- .type_base = WCD934X_INTR_LEVEL0,
- .num_type_reg = 4,
- .type_in_mask = false,
.num_regs = 4,
.irqs = wcd934x_irqs,
.num_irqs = ARRAY_SIZE(wcd934x_irqs),
+ .config_base = wcd934x_config_regs,
+ .num_config_bases = ARRAY_SIZE(wcd934x_config_regs),
+ .num_config_regs = 4,
+ .set_type_config = regmap_irq_set_type_config_simple,
};
static bool wcd934x_is_volatile_register(struct device *dev, unsigned int reg)
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c
index 1ab5e15a65eb..a5d6128fc67d 100644
--- a/drivers/mfd/wl1273-core.c
+++ b/drivers/mfd/wl1273-core.c
@@ -156,8 +156,7 @@ static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
return 0;
}
-static int wl1273_core_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int wl1273_core_probe(struct i2c_client *client)
{
struct wl1273_fm_platform_data *pdata = dev_get_platdata(&client->dev);
struct wl1273_core *core;
@@ -233,7 +232,7 @@ static struct i2c_driver wl1273_core_driver = {
.driver = {
.name = WL1273_FM_DRIVER_NAME,
},
- .probe = wl1273_core_probe,
+ .probe_new = wl1273_core_probe,
.id_table = wl1273_driver_id_table,
};
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index daa1ad036595..9dbe96e2d46a 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -21,9 +21,9 @@
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/pdata.h>
-static int wm831x_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int wm831x_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct wm831x_pdata *pdata = dev_get_platdata(&i2c->dev);
const struct of_device_id *of_id;
struct wm831x *wm831x;
@@ -102,7 +102,7 @@ static struct i2c_driver wm831x_i2c_driver = {
.of_match_table = of_match_ptr(wm831x_of_match),
.suppress_bind_attrs = true,
},
- .probe = wm831x_i2c_probe,
+ .probe_new = wm831x_i2c_probe,
.id_table = wm831x_i2c_id,
};
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c
index 48fd46800c28..1fa1dfbc9e31 100644
--- a/drivers/mfd/wm8350-i2c.c
+++ b/drivers/mfd/wm8350-i2c.c
@@ -16,8 +16,7 @@
#include <linux/regmap.h>
#include <linux/slab.h>
-static int wm8350_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int wm8350_i2c_probe(struct i2c_client *i2c)
{
struct wm8350 *wm8350;
struct wm8350_platform_data *pdata = dev_get_platdata(&i2c->dev);
@@ -53,7 +52,7 @@ static struct i2c_driver wm8350_i2c_driver = {
.name = "wm8350",
.suppress_bind_attrs = true,
},
- .probe = wm8350_i2c_probe,
+ .probe_new = wm8350_i2c_probe,
.id_table = wm8350_i2c_id,
};
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index 0fe32a05421b..5e1599ac9abc 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -118,8 +118,7 @@ void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400)
EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache);
#if IS_ENABLED(CONFIG_I2C)
-static int wm8400_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int wm8400_i2c_probe(struct i2c_client *i2c)
{
struct wm8400 *wm8400;
@@ -146,7 +145,7 @@ static struct i2c_driver wm8400_i2c_driver = {
.driver = {
.name = "WM8400",
},
- .probe = wm8400_i2c_probe,
+ .probe_new = wm8400_i2c_probe,
.id_table = wm8400_i2c_id,
};
#endif
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 7e88f5b0abe6..a89221bffde5 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -110,7 +110,6 @@ static const char *wm8958_main_supplies[] = {
"SPKVDD2",
};
-#ifdef CONFIG_PM
static int wm8994_suspend(struct device *dev)
{
struct wm8994 *wm8994 = dev_get_drvdata(dev);
@@ -213,7 +212,6 @@ err_enable:
return ret;
}
-#endif
#ifdef CONFIG_REGULATOR
static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
@@ -623,9 +621,9 @@ static const struct of_device_id wm8994_of_match[] = {
};
MODULE_DEVICE_TABLE(of, wm8994_of_match);
-static int wm8994_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int wm8994_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
const struct of_device_id *of_id;
struct wm8994 *wm8994;
int ret;
@@ -674,16 +672,16 @@ static const struct i2c_device_id wm8994_i2c_id[] = {
MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
static const struct dev_pm_ops wm8994_pm_ops = {
- SET_RUNTIME_PM_OPS(wm8994_suspend, wm8994_resume, NULL)
+ RUNTIME_PM_OPS(wm8994_suspend, wm8994_resume, NULL)
};
static struct i2c_driver wm8994_i2c_driver = {
.driver = {
.name = "wm8994",
- .pm = &wm8994_pm_ops,
+ .pm = pm_ptr(&wm8994_pm_ops),
.of_match_table = wm8994_of_match,
},
- .probe = wm8994_i2c_probe,
+ .probe_new = wm8994_i2c_probe,
.remove = wm8994_i2c_remove,
.id_table = wm8994_i2c_id,
};
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f7767afe116b..b4c65783960a 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2654,8 +2654,9 @@ static void bond_miimon_link_change(struct bonding *bond,
static void bond_miimon_commit(struct bonding *bond)
{
- struct list_head *iter;
struct slave *slave, *primary;
+ bool do_failover = false;
+ struct list_head *iter;
bond_for_each_slave(bond, slave, iter) {
switch (slave->link_new_state) {
@@ -2699,8 +2700,9 @@ static void bond_miimon_commit(struct bonding *bond)
bond_miimon_link_change(bond, slave, BOND_LINK_UP);
- if (!bond->curr_active_slave || slave == primary)
- goto do_failover;
+ if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary ||
+ slave->prio > rcu_dereference(bond->curr_active_slave)->prio)
+ do_failover = true;
continue;
@@ -2721,7 +2723,7 @@ static void bond_miimon_commit(struct bonding *bond)
bond_miimon_link_change(bond, slave, BOND_LINK_DOWN);
if (slave == rcu_access_pointer(bond->curr_active_slave))
- goto do_failover;
+ do_failover = true;
continue;
@@ -2732,8 +2734,9 @@ static void bond_miimon_commit(struct bonding *bond)
continue;
}
+ }
-do_failover:
+ if (do_failover) {
block_netpoll_tx();
bond_select_active_slave(bond);
unblock_netpoll_tx();
@@ -3531,6 +3534,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
*/
static void bond_ab_arp_commit(struct bonding *bond)
{
+ bool do_failover = false;
struct list_head *iter;
unsigned long last_tx;
struct slave *slave;
@@ -3560,8 +3564,9 @@ static void bond_ab_arp_commit(struct bonding *bond)
slave_info(bond->dev, slave->dev, "link status definitely up\n");
if (!rtnl_dereference(bond->curr_active_slave) ||
- slave == rtnl_dereference(bond->primary_slave))
- goto do_failover;
+ slave == rtnl_dereference(bond->primary_slave) ||
+ slave->prio > rtnl_dereference(bond->curr_active_slave)->prio)
+ do_failover = true;
}
@@ -3580,7 +3585,7 @@ static void bond_ab_arp_commit(struct bonding *bond)
if (slave == rtnl_dereference(bond->curr_active_slave)) {
RCU_INIT_POINTER(bond->current_arp_slave, NULL);
- goto do_failover;
+ do_failover = true;
}
continue;
@@ -3604,8 +3609,9 @@ static void bond_ab_arp_commit(struct bonding *bond)
slave->link_new_state);
continue;
}
+ }
-do_failover:
+ if (do_failover) {
block_netpoll_tx();
bond_select_active_slave(bond);
unblock_netpoll_tx();
diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
index 0aeff34e5ae1..6d638c93977b 100644
--- a/drivers/net/can/flexcan/flexcan-core.c
+++ b/drivers/net/can/flexcan/flexcan-core.c
@@ -2349,9 +2349,15 @@ static int __maybe_unused flexcan_noirq_resume(struct device *device)
if (netif_running(dev)) {
int err;
- err = pm_runtime_force_resume(device);
- if (err)
- return err;
+ /* For the wakeup in auto stop mode, no need to gate on the
+ * clock here, hardware will do this automatically.
+ */
+ if (!(device_may_wakeup(device) &&
+ priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)) {
+ err = pm_runtime_force_resume(device);
+ if (err)
+ return err;
+ }
if (device_may_wakeup(device))
flexcan_enable_wakeup_irq(priv, false);
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
index f688124d6d66..ef341c4254fc 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
@@ -545,6 +545,7 @@ static int kvaser_usb_hydra_send_simple_cmd(struct kvaser_usb *dev,
u8 cmd_no, int channel)
{
struct kvaser_cmd *cmd;
+ size_t cmd_len;
int err;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -552,6 +553,7 @@ static int kvaser_usb_hydra_send_simple_cmd(struct kvaser_usb *dev,
return -ENOMEM;
cmd->header.cmd_no = cmd_no;
+ cmd_len = kvaser_usb_hydra_cmd_size(cmd);
if (channel < 0) {
kvaser_usb_hydra_set_cmd_dest_he
(cmd, KVASER_USB_HYDRA_HE_ADDRESS_ILLEGAL);
@@ -568,7 +570,7 @@ static int kvaser_usb_hydra_send_simple_cmd(struct kvaser_usb *dev,
kvaser_usb_hydra_set_cmd_transid
(cmd, kvaser_usb_hydra_get_next_transid(dev));
- err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+ err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
if (err)
goto end;
@@ -584,6 +586,7 @@ kvaser_usb_hydra_send_simple_cmd_async(struct kvaser_usb_net_priv *priv,
{
struct kvaser_cmd *cmd;
struct kvaser_usb *dev = priv->dev;
+ size_t cmd_len;
int err;
cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
@@ -591,14 +594,14 @@ kvaser_usb_hydra_send_simple_cmd_async(struct kvaser_usb_net_priv *priv,
return -ENOMEM;
cmd->header.cmd_no = cmd_no;
+ cmd_len = kvaser_usb_hydra_cmd_size(cmd);
kvaser_usb_hydra_set_cmd_dest_he
(cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
kvaser_usb_hydra_set_cmd_transid
(cmd, kvaser_usb_hydra_get_next_transid(dev));
- err = kvaser_usb_send_cmd_async(priv, cmd,
- kvaser_usb_hydra_cmd_size(cmd));
+ err = kvaser_usb_send_cmd_async(priv, cmd, cmd_len);
if (err)
kfree(cmd);
@@ -742,6 +745,7 @@ static int kvaser_usb_hydra_get_single_capability(struct kvaser_usb *dev,
{
struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
struct kvaser_cmd *cmd;
+ size_t cmd_len;
u32 value = 0;
u32 mask = 0;
u16 cap_cmd_res;
@@ -753,13 +757,14 @@ static int kvaser_usb_hydra_get_single_capability(struct kvaser_usb *dev,
return -ENOMEM;
cmd->header.cmd_no = CMD_GET_CAPABILITIES_REQ;
+ cmd_len = kvaser_usb_hydra_cmd_size(cmd);
cmd->cap_req.cap_cmd = cpu_to_le16(cap_cmd_req);
kvaser_usb_hydra_set_cmd_dest_he(cmd, card_data->hydra.sysdbg_he);
kvaser_usb_hydra_set_cmd_transid
(cmd, kvaser_usb_hydra_get_next_transid(dev));
- err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+ err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
if (err)
goto end;
@@ -1578,6 +1583,7 @@ static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv,
struct kvaser_usb *dev = priv->dev;
struct kvaser_usb_net_hydra_priv *hydra = priv->sub_priv;
struct kvaser_cmd *cmd;
+ size_t cmd_len;
int err;
if (!hydra)
@@ -1588,6 +1594,7 @@ static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv,
return -ENOMEM;
cmd->header.cmd_no = CMD_GET_BUSPARAMS_REQ;
+ cmd_len = kvaser_usb_hydra_cmd_size(cmd);
kvaser_usb_hydra_set_cmd_dest_he
(cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
kvaser_usb_hydra_set_cmd_transid
@@ -1597,7 +1604,7 @@ static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv,
reinit_completion(&priv->get_busparams_comp);
- err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+ err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
if (err)
return err;
@@ -1624,6 +1631,7 @@ static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev,
struct kvaser_cmd *cmd;
struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
struct kvaser_usb *dev = priv->dev;
+ size_t cmd_len;
int err;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -1631,6 +1639,7 @@ static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev,
return -ENOMEM;
cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ;
+ cmd_len = kvaser_usb_hydra_cmd_size(cmd);
memcpy(&cmd->set_busparams_req.busparams_nominal, busparams,
sizeof(cmd->set_busparams_req.busparams_nominal));
@@ -1639,7 +1648,7 @@ static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev,
kvaser_usb_hydra_set_cmd_transid
(cmd, kvaser_usb_hydra_get_next_transid(dev));
- err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+ err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
kfree(cmd);
@@ -1652,6 +1661,7 @@ static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev,
struct kvaser_cmd *cmd;
struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
struct kvaser_usb *dev = priv->dev;
+ size_t cmd_len;
int err;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -1659,6 +1669,7 @@ static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev,
return -ENOMEM;
cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ;
+ cmd_len = kvaser_usb_hydra_cmd_size(cmd);
memcpy(&cmd->set_busparams_req.busparams_data, busparams,
sizeof(cmd->set_busparams_req.busparams_data));
@@ -1676,7 +1687,7 @@ static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev,
kvaser_usb_hydra_set_cmd_transid
(cmd, kvaser_usb_hydra_get_next_transid(dev));
- err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+ err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
kfree(cmd);
@@ -1804,6 +1815,7 @@ static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev)
static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev)
{
struct kvaser_cmd *cmd;
+ size_t cmd_len;
int err;
u32 flags;
struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
@@ -1813,6 +1825,7 @@ static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev)
return -ENOMEM;
cmd->header.cmd_no = CMD_GET_SOFTWARE_DETAILS_REQ;
+ cmd_len = kvaser_usb_hydra_cmd_size(cmd);
cmd->sw_detail_req.use_ext_cmd = 1;
kvaser_usb_hydra_set_cmd_dest_he
(cmd, KVASER_USB_HYDRA_HE_ADDRESS_ILLEGAL);
@@ -1820,7 +1833,7 @@ static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev)
kvaser_usb_hydra_set_cmd_transid
(cmd, kvaser_usb_hydra_get_next_transid(dev));
- err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+ err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
if (err)
goto end;
@@ -1938,6 +1951,7 @@ static int kvaser_usb_hydra_set_opt_mode(const struct kvaser_usb_net_priv *priv)
{
struct kvaser_usb *dev = priv->dev;
struct kvaser_cmd *cmd;
+ size_t cmd_len;
int err;
if ((priv->can.ctrlmode &
@@ -1953,6 +1967,7 @@ static int kvaser_usb_hydra_set_opt_mode(const struct kvaser_usb_net_priv *priv)
return -ENOMEM;
cmd->header.cmd_no = CMD_SET_DRIVERMODE_REQ;
+ cmd_len = kvaser_usb_hydra_cmd_size(cmd);
kvaser_usb_hydra_set_cmd_dest_he
(cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
kvaser_usb_hydra_set_cmd_transid
@@ -1962,7 +1977,7 @@ static int kvaser_usb_hydra_set_opt_mode(const struct kvaser_usb_net_priv *priv)
else
cmd->set_ctrlmode.mode = KVASER_USB_HYDRA_CTRLMODE_NORMAL;
- err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+ err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
kfree(cmd);
return err;
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 423f944cc34c..9b20c2ee6d62 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1996,8 +1996,7 @@ static int ksz_irq_common_setup(struct ksz_device *dev, struct ksz_irq *kirq)
irq_create_mapping(kirq->domain, n);
ret = request_threaded_irq(kirq->irq_num, NULL, ksz_irq_thread_fn,
- IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
- kirq->name, kirq);
+ IRQF_ONESHOT, kirq->name, kirq);
if (ret)
goto out;
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index e74c6b406172..908fa89444c9 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2919,9 +2919,6 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
MAC_10 | MAC_100 | MAC_1000FD;
- if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port))
- config->mac_capabilities |= MAC_2500FD;
-
/* This driver does not make use of the speed, duplex, pause or the
* advertisement in its mac_config, so it is safe to mark this driver
* as non-legacy.
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index ba4fff8690aa..242b8b325504 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -689,13 +689,12 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
/* Port 4 supports automedia if the serdes is associated with it. */
if (port == 4) {
- mv88e6xxx_reg_lock(chip);
err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
if (err < 0)
dev_err(chip->dev, "p%d: failed to read scratch\n",
port);
if (err <= 0)
- goto unlock;
+ return;
cmode = mv88e6352_get_port4_serdes_cmode(chip);
if (cmode < 0)
@@ -703,8 +702,6 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
port);
else
mv88e6xxx_translate_cmode(cmode, supported);
-unlock:
- mv88e6xxx_reg_unlock(chip);
}
}
@@ -831,7 +828,9 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
{
struct mv88e6xxx_chip *chip = ds->priv;
+ mv88e6xxx_reg_lock(chip);
chip->info->ops->phylink_get_caps(chip, port, config);
+ mv88e6xxx_reg_unlock(chip);
if (mv88e6xxx_phy_is_internal(ds, port)) {
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
@@ -3307,7 +3306,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
struct phylink_config pl_config = {};
unsigned long caps;
- mv88e6xxx_get_caps(ds, port, &pl_config);
+ chip->info->ops->phylink_get_caps(chip, port, &pl_config);
caps = pl_config.mac_capabilities;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 8671591cb750..3a79ead5219a 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -1489,23 +1489,6 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first,
rx_ring->stats.xdp_drops++;
}
-static void enetc_xdp_free(struct enetc_bdr *rx_ring, int rx_ring_first,
- int rx_ring_last)
-{
- while (rx_ring_first != rx_ring_last) {
- struct enetc_rx_swbd *rx_swbd = &rx_ring->rx_swbd[rx_ring_first];
-
- if (rx_swbd->page) {
- dma_unmap_page(rx_ring->dev, rx_swbd->dma, PAGE_SIZE,
- rx_swbd->dir);
- __free_page(rx_swbd->page);
- rx_swbd->page = NULL;
- }
- enetc_bdr_idx_inc(rx_ring, &rx_ring_first);
- }
- rx_ring->stats.xdp_redirect_failures++;
-}
-
static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
struct napi_struct *napi, int work_limit,
struct bpf_prog *prog)
@@ -1527,8 +1510,8 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
int orig_i, orig_cleaned_cnt;
struct xdp_buff xdp_buff;
struct sk_buff *skb;
- int tmp_orig_i, err;
u32 bd_status;
+ int err;
rxbd = enetc_rxbd(rx_ring, i);
bd_status = le32_to_cpu(rxbd->r.lstatus);
@@ -1615,18 +1598,16 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
break;
}
- tmp_orig_i = orig_i;
-
- while (orig_i != i) {
- enetc_flip_rx_buff(rx_ring,
- &rx_ring->rx_swbd[orig_i]);
- enetc_bdr_idx_inc(rx_ring, &orig_i);
- }
-
err = xdp_do_redirect(rx_ring->ndev, &xdp_buff, prog);
if (unlikely(err)) {
- enetc_xdp_free(rx_ring, tmp_orig_i, i);
+ enetc_xdp_drop(rx_ring, orig_i, i);
+ rx_ring->stats.xdp_redirect_failures++;
} else {
+ while (orig_i != i) {
+ enetc_flip_rx_buff(rx_ring,
+ &rx_ring->rx_swbd[orig_i]);
+ enetc_bdr_idx_inc(rx_ring, &orig_i);
+ }
xdp_redirect_frm_cnt++;
rx_ring->stats.xdp_redirect++;
}
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 5528b0af82ae..644f3c963730 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1674,6 +1674,14 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
* bridging applications.
*/
skb = build_skb(page_address(page), PAGE_SIZE);
+ if (unlikely(!skb)) {
+ page_pool_recycle_direct(rxq->page_pool, page);
+ ndev->stats.rx_dropped++;
+
+ netdev_err_once(ndev, "build_skb failed!\n");
+ goto rx_processing_done;
+ }
+
skb_reserve(skb, data_start);
skb_put(skb, pkt_len - sub_len);
skb_mark_for_recycle(skb);
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 97290fc0fddd..3c0c35ecea10 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -7525,7 +7525,7 @@ static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
{
struct e1000_hw *hw = &adapter->hw;
unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
- u32 reg, msgbuf[3];
+ u32 reg, msgbuf[3] = {};
u8 *addr = (u8 *)(&msgbuf[1]);
/* process all the same items cleared in a function level reset */
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 1e7e7071f64d..df3e26c0cf01 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -94,6 +94,8 @@ struct igc_ring {
u8 queue_index; /* logical index of the ring*/
u8 reg_idx; /* physical index of the ring */
bool launchtime_enable; /* true if LaunchTime is enabled */
+ ktime_t last_tx_cycle; /* end of the cycle with a launchtime transmission */
+ ktime_t last_ff_cycle; /* Last cycle with an active first flag */
u32 start_time;
u32 end_time;
@@ -182,6 +184,7 @@ struct igc_adapter {
ktime_t base_time;
ktime_t cycle_time;
+ bool qbv_enable;
/* OS defined structs */
struct pci_dev *pdev;
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index f7311aeb293b..a7b22639cfcd 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -321,6 +321,8 @@
#define IGC_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define IGC_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
+#define IGC_ADVTXD_TSN_CNTX_FIRST 0x00000080
+
/* Transmit Control */
#define IGC_TCTL_EN 0x00000002 /* enable Tx */
#define IGC_TCTL_PSP 0x00000008 /* pad short packets */
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 1586e1e435c6..44b1740dc098 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -1000,25 +1000,118 @@ static int igc_write_mc_addr_list(struct net_device *netdev)
return netdev_mc_count(netdev);
}
-static __le32 igc_tx_launchtime(struct igc_adapter *adapter, ktime_t txtime)
+static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime,
+ bool *first_flag, bool *insert_empty)
{
+ struct igc_adapter *adapter = netdev_priv(ring->netdev);
ktime_t cycle_time = adapter->cycle_time;
ktime_t base_time = adapter->base_time;
+ ktime_t now = ktime_get_clocktai();
+ ktime_t baset_est, end_of_cycle;
u32 launchtime;
+ s64 n;
- /* FIXME: when using ETF together with taprio, we may have a
- * case where 'delta' is larger than the cycle_time, this may
- * cause problems if we don't read the current value of
- * IGC_BASET, as the value writen into the launchtime
- * descriptor field may be misinterpreted.
+ n = div64_s64(ktime_sub_ns(now, base_time), cycle_time);
+
+ baset_est = ktime_add_ns(base_time, cycle_time * (n));
+ end_of_cycle = ktime_add_ns(baset_est, cycle_time);
+
+ if (ktime_compare(txtime, end_of_cycle) >= 0) {
+ if (baset_est != ring->last_ff_cycle) {
+ *first_flag = true;
+ ring->last_ff_cycle = baset_est;
+
+ if (ktime_compare(txtime, ring->last_tx_cycle) > 0)
+ *insert_empty = true;
+ }
+ }
+
+ /* Introducing a window at end of cycle on which packets
+ * potentially not honor launchtime. Window of 5us chosen
+ * considering software update the tail pointer and packets
+ * are dma'ed to packet buffer.
*/
- div_s64_rem(ktime_sub_ns(txtime, base_time), cycle_time, &launchtime);
+ if ((ktime_sub_ns(end_of_cycle, now) < 5 * NSEC_PER_USEC))
+ netdev_warn(ring->netdev, "Packet with txtime=%llu may not be honoured\n",
+ txtime);
+
+ ring->last_tx_cycle = end_of_cycle;
+
+ launchtime = ktime_sub_ns(txtime, baset_est);
+ if (launchtime > 0)
+ div_s64_rem(launchtime, cycle_time, &launchtime);
+ else
+ launchtime = 0;
return cpu_to_le32(launchtime);
}
+static int igc_init_empty_frame(struct igc_ring *ring,
+ struct igc_tx_buffer *buffer,
+ struct sk_buff *skb)
+{
+ unsigned int size;
+ dma_addr_t dma;
+
+ size = skb_headlen(skb);
+
+ dma = dma_map_single(ring->dev, skb->data, size, DMA_TO_DEVICE);
+ if (dma_mapping_error(ring->dev, dma)) {
+ netdev_err_once(ring->netdev, "Failed to map DMA for TX\n");
+ return -ENOMEM;
+ }
+
+ buffer->skb = skb;
+ buffer->protocol = 0;
+ buffer->bytecount = skb->len;
+ buffer->gso_segs = 1;
+ buffer->time_stamp = jiffies;
+ dma_unmap_len_set(buffer, len, skb->len);
+ dma_unmap_addr_set(buffer, dma, dma);
+
+ return 0;
+}
+
+static int igc_init_tx_empty_descriptor(struct igc_ring *ring,
+ struct sk_buff *skb,
+ struct igc_tx_buffer *first)
+{
+ union igc_adv_tx_desc *desc;
+ u32 cmd_type, olinfo_status;
+ int err;
+
+ if (!igc_desc_unused(ring))
+ return -EBUSY;
+
+ err = igc_init_empty_frame(ring, first, skb);
+ if (err)
+ return err;
+
+ cmd_type = IGC_ADVTXD_DTYP_DATA | IGC_ADVTXD_DCMD_DEXT |
+ IGC_ADVTXD_DCMD_IFCS | IGC_TXD_DCMD |
+ first->bytecount;
+ olinfo_status = first->bytecount << IGC_ADVTXD_PAYLEN_SHIFT;
+
+ desc = IGC_TX_DESC(ring, ring->next_to_use);
+ desc->read.cmd_type_len = cpu_to_le32(cmd_type);
+ desc->read.olinfo_status = cpu_to_le32(olinfo_status);
+ desc->read.buffer_addr = cpu_to_le64(dma_unmap_addr(first, dma));
+
+ netdev_tx_sent_queue(txring_txq(ring), skb->len);
+
+ first->next_to_watch = desc;
+
+ ring->next_to_use++;
+ if (ring->next_to_use == ring->count)
+ ring->next_to_use = 0;
+
+ return 0;
+}
+
+#define IGC_EMPTY_FRAME_SIZE 60
+
static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
- struct igc_tx_buffer *first,
+ __le32 launch_time, bool first_flag,
u32 vlan_macip_lens, u32 type_tucmd,
u32 mss_l4len_idx)
{
@@ -1037,26 +1130,17 @@ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
if (test_bit(IGC_RING_FLAG_TX_CTX_IDX, &tx_ring->flags))
mss_l4len_idx |= tx_ring->reg_idx << 4;
+ if (first_flag)
+ mss_l4len_idx |= IGC_ADVTXD_TSN_CNTX_FIRST;
+
context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd);
context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
-
- /* We assume there is always a valid Tx time available. Invalid times
- * should have been handled by the upper layers.
- */
- if (tx_ring->launchtime_enable) {
- struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
- ktime_t txtime = first->skb->tstamp;
-
- skb_txtime_consumed(first->skb);
- context_desc->launch_time = igc_tx_launchtime(adapter,
- txtime);
- } else {
- context_desc->launch_time = 0;
- }
+ context_desc->launch_time = launch_time;
}
-static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first)
+static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first,
+ __le32 launch_time, bool first_flag)
{
struct sk_buff *skb = first->skb;
u32 vlan_macip_lens = 0;
@@ -1096,7 +1180,8 @@ no_csum:
vlan_macip_lens |= skb_network_offset(skb) << IGC_ADVTXD_MACLEN_SHIFT;
vlan_macip_lens |= first->tx_flags & IGC_TX_FLAGS_VLAN_MASK;
- igc_tx_ctxtdesc(tx_ring, first, vlan_macip_lens, type_tucmd, 0);
+ igc_tx_ctxtdesc(tx_ring, launch_time, first_flag,
+ vlan_macip_lens, type_tucmd, 0);
}
static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
@@ -1320,6 +1405,7 @@ dma_error:
static int igc_tso(struct igc_ring *tx_ring,
struct igc_tx_buffer *first,
+ __le32 launch_time, bool first_flag,
u8 *hdr_len)
{
u32 vlan_macip_lens, type_tucmd, mss_l4len_idx;
@@ -1406,8 +1492,8 @@ static int igc_tso(struct igc_ring *tx_ring,
vlan_macip_lens |= (ip.hdr - skb->data) << IGC_ADVTXD_MACLEN_SHIFT;
vlan_macip_lens |= first->tx_flags & IGC_TX_FLAGS_VLAN_MASK;
- igc_tx_ctxtdesc(tx_ring, first, vlan_macip_lens,
- type_tucmd, mss_l4len_idx);
+ igc_tx_ctxtdesc(tx_ring, launch_time, first_flag,
+ vlan_macip_lens, type_tucmd, mss_l4len_idx);
return 1;
}
@@ -1415,11 +1501,14 @@ static int igc_tso(struct igc_ring *tx_ring,
static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
struct igc_ring *tx_ring)
{
+ bool first_flag = false, insert_empty = false;
u16 count = TXD_USE_COUNT(skb_headlen(skb));
__be16 protocol = vlan_get_protocol(skb);
struct igc_tx_buffer *first;
+ __le32 launch_time = 0;
u32 tx_flags = 0;
unsigned short f;
+ ktime_t txtime;
u8 hdr_len = 0;
int tso = 0;
@@ -1433,11 +1522,40 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
count += TXD_USE_COUNT(skb_frag_size(
&skb_shinfo(skb)->frags[f]));
- if (igc_maybe_stop_tx(tx_ring, count + 3)) {
+ if (igc_maybe_stop_tx(tx_ring, count + 5)) {
/* this is a hard error */
return NETDEV_TX_BUSY;
}
+ if (!tx_ring->launchtime_enable)
+ goto done;
+
+ txtime = skb->tstamp;
+ skb->tstamp = ktime_set(0, 0);
+ launch_time = igc_tx_launchtime(tx_ring, txtime, &first_flag, &insert_empty);
+
+ if (insert_empty) {
+ struct igc_tx_buffer *empty_info;
+ struct sk_buff *empty;
+ void *data;
+
+ empty_info = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
+ empty = alloc_skb(IGC_EMPTY_FRAME_SIZE, GFP_ATOMIC);
+ if (!empty)
+ goto done;
+
+ data = skb_put(empty, IGC_EMPTY_FRAME_SIZE);
+ memset(data, 0, IGC_EMPTY_FRAME_SIZE);
+
+ igc_tx_ctxtdesc(tx_ring, 0, false, 0, 0, 0);
+
+ if (igc_init_tx_empty_descriptor(tx_ring,
+ empty,
+ empty_info) < 0)
+ dev_kfree_skb_any(empty);
+ }
+
+done:
/* record the location of the first descriptor for this packet */
first = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
first->type = IGC_TX_BUFFER_TYPE_SKB;
@@ -1474,11 +1592,11 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
first->tx_flags = tx_flags;
first->protocol = protocol;
- tso = igc_tso(tx_ring, first, &hdr_len);
+ tso = igc_tso(tx_ring, first, launch_time, first_flag, &hdr_len);
if (tso < 0)
goto out_drop;
else if (!tso)
- igc_tx_csum(tx_ring, first);
+ igc_tx_csum(tx_ring, first, launch_time, first_flag);
igc_tx_map(tx_ring, first, hdr_len);
@@ -5925,10 +6043,16 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
bool queue_configured[IGC_MAX_TX_QUEUES] = { };
u32 start_time = 0, end_time = 0;
size_t n;
+ int i;
+
+ adapter->qbv_enable = qopt->enable;
if (!qopt->enable)
return igc_tsn_clear_schedule(adapter);
+ if (qopt->base_time < 0)
+ return -ERANGE;
+
if (adapter->base_time)
return -EALREADY;
@@ -5940,10 +6064,24 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
for (n = 0; n < qopt->num_entries; n++) {
struct tc_taprio_sched_entry *e = &qopt->entries[n];
- int i;
end_time += e->interval;
+ /* If any of the conditions below are true, we need to manually
+ * control the end time of the cycle.
+ * 1. Qbv users can specify a cycle time that is not equal
+ * to the total GCL intervals. Hence, recalculation is
+ * necessary here to exclude the time interval that
+ * exceeds the cycle time.
+ * 2. According to IEEE Std. 802.1Q-2018 section 8.6.9.2,
+ * once the end of the list is reached, it will switch
+ * to the END_OF_CYCLE state and leave the gates in the
+ * same state until the next cycle is started.
+ */
+ if (end_time > adapter->cycle_time ||
+ n + 1 == qopt->num_entries)
+ end_time = adapter->cycle_time;
+
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igc_ring *ring = adapter->tx_ring[i];
@@ -5964,6 +6102,18 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
start_time += e->interval;
}
+ /* Check whether a queue gets configured.
+ * If not, set the start and end time to be end time.
+ */
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ if (!queue_configured[i]) {
+ struct igc_ring *ring = adapter->tx_ring[i];
+
+ ring->start_time = end_time;
+ ring->end_time = end_time;
+ }
+ }
+
return 0;
}
diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c
index f975ed807da1..bb10d7b65232 100644
--- a/drivers/net/ethernet/intel/igc/igc_tsn.c
+++ b/drivers/net/ethernet/intel/igc/igc_tsn.c
@@ -36,7 +36,7 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
{
unsigned int new_flags = adapter->flags & ~IGC_FLAG_TSN_ANY_ENABLED;
- if (adapter->base_time)
+ if (adapter->qbv_enable)
new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
if (is_any_launchtime(adapter))
@@ -140,15 +140,8 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
wr32(IGC_STQT(i), ring->start_time);
wr32(IGC_ENDQT(i), ring->end_time);
- if (adapter->base_time) {
- /* If we have a base_time we are in "taprio"
- * mode and we need to be strict about the
- * cycles: only transmit a packet if it can be
- * completed during that cycle.
- */
- txqctl |= IGC_TXQCTL_STRICT_CYCLE |
- IGC_TXQCTL_STRICT_END;
- }
+ txqctl |= IGC_TXQCTL_STRICT_CYCLE |
+ IGC_TXQCTL_STRICT_END;
if (ring->launchtime_enable)
txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
index 895bfff550d2..e0b206247f2e 100644
--- a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
+++ b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
@@ -83,6 +83,8 @@ static void vcap_debugfs_show_rule_keyfield(struct vcap_control *vctrl,
hex = true;
break;
case VCAP_FIELD_U128:
+ value = data->u128.value;
+ mask = data->u128.mask;
if (key == VCAP_KF_L3_IP6_SIP || key == VCAP_KF_L3_IP6_DIP) {
u8 nvalue[16], nmask[16];
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 8073d7a90a26..c5687d94ea88 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -3912,6 +3912,7 @@ abort_with_slices:
myri10ge_free_slices(mgp);
abort_with_firmware:
+ kfree(mgp->msix_vectors);
myri10ge_dummy_rdma(mgp, 0);
abort_with_ioremap:
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 2314cf55e821..09053373288f 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -2509,7 +2509,7 @@ static int nfp_net_read_caps(struct nfp_net *nn)
{
/* Get some of the read-only fields from the BAR */
nn->cap = nn_readl(nn, NFP_NET_CFG_CAP);
- nn->cap_w1 = nn_readq(nn, NFP_NET_CFG_CAP_WORD1);
+ nn->cap_w1 = nn_readl(nn, NFP_NET_CFG_CAP_WORD1);
nn->max_mtu = nn_readl(nn, NFP_NET_CFG_MAX_MTU);
/* ABI 4.x and ctrl vNIC always use chained metadata, in other cases
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
index eecd52ed1ed2..f4d434c379e7 100644
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -1159,10 +1159,12 @@ static int r6040_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
err = register_netdev(dev);
if (err) {
dev_err(&pdev->dev, "Failed to register net device\n");
- goto err_out_mdio_unregister;
+ goto err_out_phy_disconnect;
}
return 0;
+err_out_phy_disconnect:
+ phy_disconnect(dev->phydev);
err_out_mdio_unregister:
mdiobus_unregister(lp->mii_bus);
err_out_mdio:
@@ -1186,6 +1188,7 @@ static void r6040_remove_one(struct pci_dev *pdev)
struct r6040_private *lp = netdev_priv(dev);
unregister_netdev(dev);
+ phy_disconnect(dev->phydev);
mdiobus_unregister(lp->mii_bus);
mdiobus_free(lp->mii_bus);
netif_napi_del(&lp->napi);
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 33f723a9f471..b4e0fc7f65bd 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -2903,12 +2903,12 @@ static int ravb_remove(struct platform_device *pdev)
priv->desc_bat_dma);
/* Set reset mode */
ravb_write(ndev, CCC_OPC_RESET, CCC);
- pm_runtime_put_sync(&pdev->dev);
unregister_netdev(ndev);
if (info->nc_queues)
netif_napi_del(&priv->napi[RAVB_NC]);
netif_napi_del(&priv->napi[RAVB_BE]);
ravb_mdio_release(priv);
+ pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
reset_control_assert(priv->rstc);
free_netdev(ndev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ec64b65dee34..c6951c976f5d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7099,6 +7099,7 @@ int stmmac_dvr_probe(struct device *device,
priv->wq = create_singlethread_workqueue("stmmac_wq");
if (!priv->wq) {
dev_err(priv->device, "failed to create workqueue\n");
+ ret = -ENOMEM;
goto error_wq_init;
}
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index 9decb0c7961b..ecbde83b5243 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -2878,7 +2878,6 @@ static int am65_cpsw_nuss_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int am65_cpsw_nuss_suspend(struct device *dev)
{
struct am65_cpsw_common *common = dev_get_drvdata(dev);
@@ -2964,10 +2963,9 @@ static int am65_cpsw_nuss_resume(struct device *dev)
return 0;
}
-#endif /* CONFIG_PM_SLEEP */
static const struct dev_pm_ops am65_cpsw_nuss_dev_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(am65_cpsw_nuss_suspend, am65_cpsw_nuss_resume)
+ SYSTEM_SLEEP_PM_OPS(am65_cpsw_nuss_suspend, am65_cpsw_nuss_resume)
};
static struct platform_driver am65_cpsw_nuss_driver = {
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 937f5b1f04ff..bf8ac7a3ded7 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -2593,7 +2593,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
const struct macsec_ops *ops;
struct macsec_context ctx;
struct macsec_dev *macsec;
- int ret;
+ int ret = 0;
if (!attrs[MACSEC_ATTR_IFINDEX])
return -EINVAL;
@@ -2606,28 +2606,36 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
macsec_genl_offload_policy, NULL))
return -EINVAL;
+ rtnl_lock();
+
dev = get_dev_from_nl(genl_info_net(info), attrs);
- if (IS_ERR(dev))
- return PTR_ERR(dev);
+ if (IS_ERR(dev)) {
+ ret = PTR_ERR(dev);
+ goto out;
+ }
macsec = macsec_priv(dev);
- if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE])
- return -EINVAL;
+ if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]) {
+ ret = -EINVAL;
+ goto out;
+ }
offload = nla_get_u8(tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]);
if (macsec->offload == offload)
- return 0;
+ goto out;
/* Check if the offloading mode is supported by the underlying layers */
if (offload != MACSEC_OFFLOAD_OFF &&
- !macsec_check_offload(offload, macsec))
- return -EOPNOTSUPP;
+ !macsec_check_offload(offload, macsec)) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
/* Check if the net device is busy. */
- if (netif_running(dev))
- return -EBUSY;
-
- rtnl_lock();
+ if (netif_running(dev)) {
+ ret = -EBUSY;
+ goto out;
+ }
prev_offload = macsec->offload;
macsec->offload = offload;
@@ -2662,7 +2670,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
rollback:
macsec->offload = prev_offload;
-
+out:
rtnl_unlock();
return ret;
}
diff --git a/drivers/net/mctp/mctp-serial.c b/drivers/net/mctp/mctp-serial.c
index 7cd103fd34ef..9f9eaf896047 100644
--- a/drivers/net/mctp/mctp-serial.c
+++ b/drivers/net/mctp/mctp-serial.c
@@ -35,6 +35,8 @@
#define BYTE_FRAME 0x7e
#define BYTE_ESC 0x7d
+#define FCS_INIT 0xffff
+
static DEFINE_IDA(mctp_serial_ida);
enum mctp_serial_state {
@@ -123,7 +125,7 @@ static void mctp_serial_tx_work(struct work_struct *work)
buf[2] = dev->txlen;
if (!dev->txpos)
- dev->txfcs = crc_ccitt(0, buf + 1, 2);
+ dev->txfcs = crc_ccitt(FCS_INIT, buf + 1, 2);
txlen = write_chunk(dev, buf + dev->txpos, 3 - dev->txpos);
if (txlen <= 0) {
@@ -303,7 +305,7 @@ static void mctp_serial_push_header(struct mctp_serial *dev, unsigned char c)
case 1:
if (c == MCTP_SERIAL_VERSION) {
dev->rxpos++;
- dev->rxfcs = crc_ccitt_byte(0, c);
+ dev->rxfcs = crc_ccitt_byte(FCS_INIT, c);
} else {
dev->rxstate = STATE_ERR;
}
diff --git a/drivers/net/wireguard/timers.c b/drivers/net/wireguard/timers.c
index b5706b6718b1..53d8a57a0dfa 100644
--- a/drivers/net/wireguard/timers.c
+++ b/drivers/net/wireguard/timers.c
@@ -46,7 +46,7 @@ static void wg_expired_retransmit_handshake(struct timer_list *timer)
if (peer->timer_handshake_attempts > MAX_TIMER_HANDSHAKES) {
pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d attempts, giving up\n",
peer->device->dev->name, peer->internal_id,
- &peer->endpoint.addr, MAX_TIMER_HANDSHAKES + 2);
+ &peer->endpoint.addr, (int)MAX_TIMER_HANDSHAKES + 2);
del_timer(&peer->timer_send_keepalive);
/* We drop all packets without a keypair and don't try again,
@@ -64,7 +64,7 @@ static void wg_expired_retransmit_handshake(struct timer_list *timer)
++peer->timer_handshake_attempts;
pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d seconds, retrying (try %d)\n",
peer->device->dev->name, peer->internal_id,
- &peer->endpoint.addr, REKEY_TIMEOUT,
+ &peer->endpoint.addr, (int)REKEY_TIMEOUT,
peer->timer_handshake_attempts + 1);
/* We clear the endpoint address src address, in case this is
@@ -94,7 +94,7 @@ static void wg_expired_new_handshake(struct timer_list *timer)
pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after %d seconds\n",
peer->device->dev->name, peer->internal_id,
- &peer->endpoint.addr, KEEPALIVE_TIMEOUT + REKEY_TIMEOUT);
+ &peer->endpoint.addr, (int)(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT));
/* We clear the endpoint address src address, in case this is the cause
* of trouble.
*/
@@ -126,7 +126,7 @@ static void wg_queued_expired_zero_key_material(struct work_struct *work)
pr_debug("%s: Zeroing out all keys for peer %llu (%pISpfsc), since we haven't received a new one in %d seconds\n",
peer->device->dev->name, peer->internal_id,
- &peer->endpoint.addr, REJECT_AFTER_TIME * 3);
+ &peer->endpoint.addr, (int)REJECT_AFTER_TIME * 3);
wg_noise_handshake_clear(&peer->handshake);
wg_noise_keypairs_clear(&peer->keypairs);
wg_peer_put(peer);
diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c
index d9f6367b9993..f0cac1900552 100644
--- a/drivers/nfc/pn533/pn533.c
+++ b/drivers/nfc/pn533/pn533.c
@@ -1295,6 +1295,8 @@ static int pn533_poll_dep_complete(struct pn533 *dev, void *arg,
if (IS_ERR(resp))
return PTR_ERR(resp);
+ memset(&nfc_target, 0, sizeof(struct nfc_target));
+
rsp = (struct pn533_cmd_jump_dep_response *)resp->data;
rc = rsp->status & PN533_CMD_RET_MASK;
@@ -1926,6 +1928,8 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
dev_dbg(dev->dev, "Creating new target\n");
+ memset(&nfc_target, 0, sizeof(struct nfc_target));
+
nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
nfc_target.nfcid1_len = 10;
memcpy(nfc_target.nfcid1, rsp->nfcid3t, nfc_target.nfcid1_len);
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index b69b89166b6b..8cedc1ef496c 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -1537,6 +1537,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid)
queue->sock->sk->sk_rcvtimeo = 10 * HZ;
queue->sock->sk->sk_allocation = GFP_ATOMIC;
+ queue->sock->sk->sk_use_task_frag = false;
nvme_tcp_set_queue_io_cpu(queue);
queue->request = NULL;
queue->data_remaining = 0;
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 60d13a949bc5..dae023d783a2 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -282,8 +282,8 @@ config PWM_IQS620A
config PWM_JZ4740
tristate "Ingenic JZ47xx PWM support"
- depends on MIPS || COMPILE_TEST
- depends on COMMON_CLK
+ depends on MACH_INGENIC || COMPILE_TEST
+ depends on COMMON_CLK && OF
select MFD_SYSCON
help
Generic PWM framework driver for Ingenic JZ47xx based
@@ -434,7 +434,7 @@ config PWM_PCA9685
config PWM_PXA
tristate "PXA PWM support"
- depends on ARCH_PXA || COMPILE_TEST
+ depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST
depends on HAS_IOMEM
help
Generic PWM framework driver for PXA.
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index d333e7422f4a..e01147f66e15 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -27,7 +27,10 @@
static DEFINE_MUTEX(pwm_lookup_lock);
static LIST_HEAD(pwm_lookup_list);
+
+/* protects access to pwm_chips, allocated_pwms, and pwm_tree */
static DEFINE_MUTEX(pwm_lock);
+
static LIST_HEAD(pwm_chips);
static DECLARE_BITMAP(allocated_pwms, MAX_PWMS);
static RADIX_TREE(pwm_tree, GFP_KERNEL);
@@ -37,6 +40,7 @@ static struct pwm_device *pwm_to_device(unsigned int pwm)
return radix_tree_lookup(&pwm_tree, pwm);
}
+/* Called with pwm_lock held */
static int alloc_pwms(unsigned int count)
{
unsigned int start;
@@ -47,9 +51,12 @@ static int alloc_pwms(unsigned int count)
if (start + count > MAX_PWMS)
return -ENOSPC;
+ bitmap_set(allocated_pwms, start, count);
+
return start;
}
+/* Called with pwm_lock held */
static void free_pwms(struct pwm_chip *chip)
{
unsigned int i;
@@ -108,8 +115,13 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
}
if (pwm->chip->ops->get_state) {
- pwm->chip->ops->get_state(pwm->chip, pwm, &pwm->state);
- trace_pwm_get(pwm, &pwm->state);
+ struct pwm_state state;
+
+ err = pwm->chip->ops->get_state(pwm->chip, pwm, &state);
+ trace_pwm_get(pwm, &state, err);
+
+ if (!err)
+ pwm->state = state;
if (IS_ENABLED(CONFIG_PWM_DEBUG))
pwm->last = pwm->state;
@@ -267,20 +279,21 @@ int pwmchip_add(struct pwm_chip *chip)
if (!pwm_ops_check(chip))
return -EINVAL;
+ chip->pwms = kcalloc(chip->npwm, sizeof(*pwm), GFP_KERNEL);
+ if (!chip->pwms)
+ return -ENOMEM;
+
mutex_lock(&pwm_lock);
ret = alloc_pwms(chip->npwm);
- if (ret < 0)
- goto out;
+ if (ret < 0) {
+ mutex_unlock(&pwm_lock);
+ kfree(chip->pwms);
+ return ret;
+ }
chip->base = ret;
- chip->pwms = kcalloc(chip->npwm, sizeof(*pwm), GFP_KERNEL);
- if (!chip->pwms) {
- ret = -ENOMEM;
- goto out;
- }
-
for (i = 0; i < chip->npwm; i++) {
pwm = &chip->pwms[i];
@@ -291,23 +304,16 @@ int pwmchip_add(struct pwm_chip *chip)
radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
}
- bitmap_set(allocated_pwms, chip->base, chip->npwm);
-
- INIT_LIST_HEAD(&chip->list);
list_add(&chip->list, &pwm_chips);
- ret = 0;
+ mutex_unlock(&pwm_lock);
if (IS_ENABLED(CONFIG_OF))
of_pwmchip_add(chip);
-out:
- mutex_unlock(&pwm_lock);
-
- if (!ret)
- pwmchip_sysfs_export(chip);
+ pwmchip_sysfs_export(chip);
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(pwmchip_add);
@@ -457,8 +463,11 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
* checks.
*/
- chip->ops->get_state(chip, pwm, &s1);
- trace_pwm_get(pwm, &s1);
+ err = chip->ops->get_state(chip, pwm, &s1);
+ trace_pwm_get(pwm, &s1, err);
+ if (err)
+ /* If that failed there isn't much to debug */
+ return;
/*
* The lowlevel driver either ignored .polarity (which is a bug) or as
@@ -514,16 +523,17 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
/* reapply the state that the driver reported being configured. */
err = chip->ops->apply(chip, pwm, &s1);
+ trace_pwm_apply(pwm, &s1, err);
if (err) {
*last = s1;
dev_err(chip->dev, "failed to reapply current setting\n");
return;
}
- trace_pwm_apply(pwm, &s1);
-
- chip->ops->get_state(chip, pwm, last);
- trace_pwm_get(pwm, last);
+ err = chip->ops->get_state(chip, pwm, last);
+ trace_pwm_get(pwm, last, err);
+ if (err)
+ return;
/* reapplication of the current state should give an exact match */
if (s1.enabled != last->enabled ||
@@ -571,11 +581,10 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
return 0;
err = chip->ops->apply(chip, pwm, state);
+ trace_pwm_apply(pwm, state, err);
if (err)
return err;
- trace_pwm_apply(pwm, state);
-
pwm->state = *state;
/*
@@ -1179,8 +1188,7 @@ DEFINE_SEQ_ATTRIBUTE(pwm_debugfs);
static int __init pwm_debugfs_init(void)
{
- debugfs_create_file("pwm", S_IFREG | 0444, NULL, NULL,
- &pwm_debugfs_fops);
+ debugfs_create_file("pwm", 0444, NULL, NULL, &pwm_debugfs_fops);
return 0;
}
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 8e00a4286145..cdbc23649032 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -356,8 +356,8 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
-static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
u32 sr, cmr;
@@ -396,6 +396,8 @@ static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->polarity = PWM_POLARITY_INVERSED;
else
state->polarity = PWM_POLARITY_NORMAL;
+
+ return 0;
}
static const struct pwm_ops atmel_pwm_ops = {
diff --git a/drivers/pwm/pwm-bcm-iproc.c b/drivers/pwm/pwm-bcm-iproc.c
index 7251037d4dd5..97ec131eb7c1 100644
--- a/drivers/pwm/pwm-bcm-iproc.c
+++ b/drivers/pwm/pwm-bcm-iproc.c
@@ -68,8 +68,8 @@ static void iproc_pwmc_disable(struct iproc_pwmc *ip, unsigned int channel)
ndelay(400);
}
-static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct iproc_pwmc *ip = to_iproc_pwmc(chip);
u64 tmp, multi, rate;
@@ -91,7 +91,7 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
if (rate == 0) {
state->period = 0;
state->duty_cycle = 0;
- return;
+ return 0;
}
value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET);
@@ -107,6 +107,8 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
value = readl(ip->base + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm));
tmp = (value & IPROC_PWM_PERIOD_MAX) * multi;
state->duty_cycle = div64_u64(tmp, rate);
+
+ return 0;
}
static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
diff --git a/drivers/pwm/pwm-crc.c b/drivers/pwm/pwm-crc.c
index 7b357d1cf642..4703b4a0b6e4 100644
--- a/drivers/pwm/pwm-crc.c
+++ b/drivers/pwm/pwm-crc.c
@@ -121,8 +121,8 @@ static int crc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
-static void crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct crystalcove_pwm *crc_pwm = to_crc_pwm(chip);
struct device *dev = crc_pwm->chip.dev;
@@ -132,13 +132,13 @@ static void crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
error = regmap_read(crc_pwm->regmap, PWM0_CLK_DIV, &clk_div_reg);
if (error) {
dev_err(dev, "Error reading PWM0_CLK_DIV %d\n", error);
- return;
+ return error;
}
error = regmap_read(crc_pwm->regmap, PWM0_DUTY_CYCLE, &duty_cycle_reg);
if (error) {
dev_err(dev, "Error reading PWM0_DUTY_CYCLE %d\n", error);
- return;
+ return error;
}
clk_div = (clk_div_reg & ~PWM_OUTPUT_ENABLE) + 1;
@@ -149,6 +149,8 @@ static void crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
DIV_ROUND_UP_ULL(duty_cycle_reg * state->period, PWM_MAX_LEVEL);
state->polarity = PWM_POLARITY_NORMAL;
state->enabled = !!(clk_div_reg & PWM_OUTPUT_ENABLE);
+
+ return 0;
}
static const struct pwm_ops crc_pwm_ops = {
diff --git a/drivers/pwm/pwm-cros-ec.c b/drivers/pwm/pwm-cros-ec.c
index 7f10f56c3eb6..86df6702cb83 100644
--- a/drivers/pwm/pwm-cros-ec.c
+++ b/drivers/pwm/pwm-cros-ec.c
@@ -183,8 +183,8 @@ static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
-static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct cros_ec_pwm_device *ec_pwm = pwm_to_cros_ec_pwm(chip);
struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
@@ -193,7 +193,7 @@ static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
ret = cros_ec_pwm_get_duty(ec_pwm, pwm->hwpwm);
if (ret < 0) {
dev_err(chip->dev, "error getting initial duty: %d\n", ret);
- return;
+ return ret;
}
state->enabled = (ret > 0);
@@ -212,6 +212,8 @@ static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->duty_cycle = channel->duty_cycle;
else
state->duty_cycle = ret;
+
+ return 0;
}
static struct pwm_device *
diff --git a/drivers/pwm/pwm-dwc.c b/drivers/pwm/pwm-dwc.c
index 7568300bb11e..bd2308812096 100644
--- a/drivers/pwm/pwm-dwc.c
+++ b/drivers/pwm/pwm-dwc.c
@@ -163,8 +163,8 @@ static int dwc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
-static void dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct dwc_pwm *dwc = to_dwc_pwm(chip);
u64 duty, period;
@@ -188,6 +188,8 @@ static void dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->polarity = PWM_POLARITY_INVERSED;
pm_runtime_put_sync(chip->dev);
+
+ return 0;
}
static const struct pwm_ops dwc_pwm_ops = {
diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index 0247757f9a72..5caadbd6194e 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -65,13 +65,12 @@ static void ftm_clear_write_protection(struct fsl_pwm_chip *fpc)
regmap_read(fpc->regmap, FTM_FMS, &val);
if (val & FTM_FMS_WPEN)
- regmap_update_bits(fpc->regmap, FTM_MODE, FTM_MODE_WPDIS,
- FTM_MODE_WPDIS);
+ regmap_set_bits(fpc->regmap, FTM_MODE, FTM_MODE_WPDIS);
}
static void ftm_set_write_protection(struct fsl_pwm_chip *fpc)
{
- regmap_update_bits(fpc->regmap, FTM_FMS, FTM_FMS_WPEN, FTM_FMS_WPEN);
+ regmap_set_bits(fpc->regmap, FTM_FMS, FTM_FMS_WPEN);
}
static bool fsl_pwm_periodcfg_are_equal(const struct fsl_pwm_periodcfg *a,
@@ -94,8 +93,7 @@ static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
ret = clk_prepare_enable(fpc->ipg_clk);
if (!ret && fpc->soc->has_enable_bits) {
mutex_lock(&fpc->lock);
- regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
- BIT(pwm->hwpwm + 16));
+ regmap_set_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16));
mutex_unlock(&fpc->lock);
}
@@ -108,8 +106,7 @@ static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
if (fpc->soc->has_enable_bits) {
mutex_lock(&fpc->lock);
- regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
- 0);
+ regmap_clear_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16));
mutex_unlock(&fpc->lock);
}
@@ -317,8 +314,8 @@ static int fsl_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (!newstate->enabled) {
if (oldstate->enabled) {
- regmap_update_bits(fpc->regmap, FTM_OUTMASK,
- BIT(pwm->hwpwm), BIT(pwm->hwpwm));
+ regmap_set_bits(fpc->regmap, FTM_OUTMASK,
+ BIT(pwm->hwpwm));
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
clk_disable_unprepare(fpc->clk[fpc->period.clk_select]);
}
@@ -342,8 +339,7 @@ static int fsl_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
goto end_mutex;
}
- regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm),
- 0);
+ regmap_clear_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm));
}
end_mutex:
diff --git a/drivers/pwm/pwm-hibvt.c b/drivers/pwm/pwm-hibvt.c
index 333f1b18ff4e..12c05c155cab 100644
--- a/drivers/pwm/pwm-hibvt.c
+++ b/drivers/pwm/pwm-hibvt.c
@@ -128,8 +128,8 @@ static void hibvt_pwm_set_polarity(struct pwm_chip *chip,
PWM_POLARITY_MASK, (0x0 << PWM_POLARITY_SHIFT));
}
-static void hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
void __iomem *base;
@@ -146,6 +146,8 @@ static void hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm));
state->enabled = (PWM_ENABLE_MASK & value);
+
+ return 0;
}
static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c
index 0fccf061ab95..89362afe3c91 100644
--- a/drivers/pwm/pwm-img.c
+++ b/drivers/pwm/pwm-img.c
@@ -161,9 +161,9 @@ static int img_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
val |= BIT(pwm->hwpwm);
img_pwm_writel(imgchip, PWM_CTRL_CFG, val);
- regmap_update_bits(imgchip->periph_regs, PERIP_PWM_PDM_CONTROL,
- PERIP_PWM_PDM_CONTROL_CH_MASK <<
- PERIP_PWM_PDM_CONTROL_CH_SHIFT(pwm->hwpwm), 0);
+ regmap_clear_bits(imgchip->periph_regs, PERIP_PWM_PDM_CONTROL,
+ PERIP_PWM_PDM_CONTROL_CH_MASK <<
+ PERIP_PWM_PDM_CONTROL_CH_SHIFT(pwm->hwpwm));
return 0;
}
@@ -397,11 +397,10 @@ static int img_pwm_resume(struct device *dev)
for (i = 0; i < imgchip->chip.npwm; i++)
if (imgchip->suspend_ctrl_cfg & BIT(i))
- regmap_update_bits(imgchip->periph_regs,
- PERIP_PWM_PDM_CONTROL,
- PERIP_PWM_PDM_CONTROL_CH_MASK <<
- PERIP_PWM_PDM_CONTROL_CH_SHIFT(i),
- 0);
+ regmap_clear_bits(imgchip->periph_regs,
+ PERIP_PWM_PDM_CONTROL,
+ PERIP_PWM_PDM_CONTROL_CH_MASK <<
+ PERIP_PWM_PDM_CONTROL_CH_SHIFT(i));
if (pm_runtime_status_suspended(dev))
img_pwm_runtime_suspend(dev);
diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c
index e5e7b7c339a8..ed1aad96fff0 100644
--- a/drivers/pwm/pwm-imx-tpm.c
+++ b/drivers/pwm/pwm-imx-tpm.c
@@ -132,9 +132,9 @@ static int pwm_imx_tpm_round_state(struct pwm_chip *chip,
return 0;
}
-static void pwm_imx_tpm_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
+static int pwm_imx_tpm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip);
u32 rate, val, prescale;
@@ -164,6 +164,8 @@ static void pwm_imx_tpm_get_state(struct pwm_chip *chip,
/* get channel status */
state->enabled = FIELD_GET(PWM_IMX_TPM_CnSC_ELS, val) ? true : false;
+
+ return 0;
}
/* this function is supposed to be called with mutex hold */
diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
index ea91a2f81a9f..29a3089c534c 100644
--- a/drivers/pwm/pwm-imx27.c
+++ b/drivers/pwm/pwm-imx27.c
@@ -118,8 +118,8 @@ static void pwm_imx27_clk_disable_unprepare(struct pwm_imx27_chip *imx)
clk_disable_unprepare(imx->clk_ipg);
}
-static void pwm_imx27_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm, struct pwm_state *state)
+static int pwm_imx27_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm, struct pwm_state *state)
{
struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
u32 period, prescaler, pwm_clk, val;
@@ -128,7 +128,7 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
ret = pwm_imx27_clk_prepare_enable(imx);
if (ret < 0)
- return;
+ return ret;
val = readl(imx->mmio_base + MX3_PWMCR);
@@ -170,6 +170,8 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
state->duty_cycle = DIV_ROUND_UP_ULL(tmp, pwm_clk);
pwm_imx27_clk_disable_unprepare(imx);
+
+ return 0;
}
static void pwm_imx27_sw_reset(struct pwm_chip *chip)
diff --git a/drivers/pwm/pwm-intel-lgm.c b/drivers/pwm/pwm-intel-lgm.c
index b66c35074087..0cd7dd548e82 100644
--- a/drivers/pwm/pwm-intel-lgm.c
+++ b/drivers/pwm/pwm-intel-lgm.c
@@ -86,8 +86,8 @@ static int lgm_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return lgm_pwm_enable(chip, 1);
}
-static void lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
u32 duty, val;
@@ -100,6 +100,8 @@ static void lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
regmap_read(pc->regmap, LGM_PWM_FAN_CON0, &val);
duty = FIELD_GET(LGM_PWM_FAN_DC_MSK, val);
state->duty_cycle = DIV_ROUND_UP(duty * pc->period, LGM_PWM_MAX_DUTY_CYCLE);
+
+ return 0;
}
static const struct pwm_ops lgm_pwm_ops = {
diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
index 54bd95a5cab0..4987ca940b64 100644
--- a/drivers/pwm/pwm-iqs620a.c
+++ b/drivers/pwm/pwm-iqs620a.c
@@ -47,8 +47,8 @@ static int iqs620_pwm_init(struct iqs620_pwm_private *iqs620_pwm,
int ret;
if (!duty_scale)
- return regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
- IQS620_PWR_SETTINGS_PWM_OUT, 0);
+ return regmap_clear_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
+ IQS620_PWR_SETTINGS_PWM_OUT);
ret = regmap_write(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE,
duty_scale - 1);
@@ -104,8 +104,8 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return ret;
}
-static void iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct iqs620_pwm_private *iqs620_pwm;
@@ -126,6 +126,8 @@ static void iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
mutex_unlock(&iqs620_pwm->lock);
state->period = IQS620_PWM_PERIOD_NS;
+
+ return 0;
}
static int iqs620_pwm_notifier(struct notifier_block *notifier,
diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c
index a5fdf97c0d2e..3b7067f6cd0d 100644
--- a/drivers/pwm/pwm-jz4740.c
+++ b/drivers/pwm/pwm-jz4740.c
@@ -88,8 +88,7 @@ static int jz4740_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
struct jz4740_pwm_chip *jz = to_jz4740(chip);
/* Enable PWM output */
- regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
- TCU_TCSR_PWM_EN, TCU_TCSR_PWM_EN);
+ regmap_set_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm), TCU_TCSR_PWM_EN);
/* Start counter */
regmap_write(jz->map, TCU_REG_TESR, BIT(pwm->hwpwm));
@@ -113,8 +112,7 @@ static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
* In TCU2 mode (channel 1/2 on JZ4750+), this must be done before the
* counter is stopped, while in TCU1 mode the order does not matter.
*/
- regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
- TCU_TCSR_PWM_EN, 0);
+ regmap_clear_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm), TCU_TCSR_PWM_EN);
/* Stop counter */
regmap_write(jz->map, TCU_REG_TECR, BIT(pwm->hwpwm));
@@ -184,8 +182,8 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
regmap_write(jz4740->map, TCU_REG_TDFRc(pwm->hwpwm), period);
/* Set abrupt shutdown */
- regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
- TCU_TCSR_PWM_SD, TCU_TCSR_PWM_SD);
+ regmap_set_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
+ TCU_TCSR_PWM_SD);
/*
* Set polarity.
@@ -248,19 +246,18 @@ static int jz4740_pwm_probe(struct platform_device *pdev)
return devm_pwmchip_add(dev, &jz4740->chip);
}
-static const struct soc_info __maybe_unused jz4740_soc_info = {
+static const struct soc_info jz4740_soc_info = {
.num_pwms = 8,
};
-static const struct soc_info __maybe_unused jz4725b_soc_info = {
+static const struct soc_info jz4725b_soc_info = {
.num_pwms = 6,
};
-static const struct soc_info __maybe_unused x1000_soc_info = {
+static const struct soc_info x1000_soc_info = {
.num_pwms = 5,
};
-#ifdef CONFIG_OF
static const struct of_device_id jz4740_pwm_dt_ids[] = {
{ .compatible = "ingenic,jz4740-pwm", .data = &jz4740_soc_info },
{ .compatible = "ingenic,jz4725b-pwm", .data = &jz4725b_soc_info },
@@ -268,12 +265,11 @@ static const struct of_device_id jz4740_pwm_dt_ids[] = {
{},
};
MODULE_DEVICE_TABLE(of, jz4740_pwm_dt_ids);
-#endif
static struct platform_driver jz4740_pwm_driver = {
.driver = {
.name = "jz4740-pwm",
- .of_match_table = of_match_ptr(jz4740_pwm_dt_ids),
+ .of_match_table = jz4740_pwm_dt_ids,
},
.probe = jz4740_pwm_probe,
};
diff --git a/drivers/pwm/pwm-keembay.c b/drivers/pwm/pwm-keembay.c
index 733811b05721..ac02d8bb4a0b 100644
--- a/drivers/pwm/pwm-keembay.c
+++ b/drivers/pwm/pwm-keembay.c
@@ -89,8 +89,8 @@ static void keembay_pwm_disable(struct keembay_pwm *priv, int ch)
KMB_PWM_LEADIN_OFFSET(ch));
}
-static void keembay_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int keembay_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct keembay_pwm *priv = to_keembay_pwm_dev(chip);
unsigned long long high, low;
@@ -113,6 +113,8 @@ static void keembay_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->duty_cycle = DIV_ROUND_UP_ULL(high, clk_rate);
state->period = DIV_ROUND_UP_ULL(high + low, clk_rate);
state->polarity = PWM_POLARITY_NORMAL;
+
+ return 0;
}
static int keembay_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
index 763f2e3a146d..378e1df944dc 100644
--- a/drivers/pwm/pwm-lpc18xx-sct.c
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -175,7 +175,7 @@ static void lpc18xx_pwm_config_duty(struct pwm_chip *chip,
u32 val;
/*
- * With clk_rate < NSEC_PER_SEC this cannot overflow.
+ * With clk_rate <= NSEC_PER_SEC this cannot overflow.
* With duty_ns <= period_ns < max_period_ns this also fits into an u32.
*/
val = mul_u64_u64_div_u64(duty_ns, lpc18xx_pwm->clk_rate, NSEC_PER_SEC);
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index bb740346b699..23fe332b2394 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -205,8 +205,8 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return ret;
}
-static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct pwm_lpss_chip *lpwm = to_lpwm(chip);
unsigned long base_unit_range;
@@ -236,6 +236,8 @@ static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->enabled = !!(ctrl & PWM_ENABLE);
pm_runtime_put(chip->dev);
+
+ return 0;
}
static const struct pwm_ops pwm_lpss_ops = {
diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 6901a44dc428..5b5eeaff35da 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -296,7 +296,7 @@ static const struct pwm_mediatek_of_data mt6795_pwm_data = {
static const struct pwm_mediatek_of_data mt7622_pwm_data = {
.num_pwms = 6,
.pwm45_fixup = false,
- .has_ck_26m_sel = false,
+ .has_ck_26m_sel = true,
};
static const struct pwm_mediatek_of_data mt7623_pwm_data = {
@@ -329,6 +329,12 @@ static const struct pwm_mediatek_of_data mt8365_pwm_data = {
.has_ck_26m_sel = true,
};
+static const struct pwm_mediatek_of_data mt7986_pwm_data = {
+ .num_pwms = 2,
+ .pwm45_fixup = false,
+ .has_ck_26m_sel = true,
+};
+
static const struct pwm_mediatek_of_data mt8516_pwm_data = {
.num_pwms = 5,
.pwm45_fixup = false,
@@ -342,6 +348,7 @@ static const struct of_device_id pwm_mediatek_of_match[] = {
{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
{ .compatible = "mediatek,mt7628-pwm", .data = &mt7628_pwm_data },
{ .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
+ { .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
{ .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
{ .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 57112f438c6d..16d79ca5d8f5 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -318,8 +318,8 @@ static unsigned int meson_pwm_cnt_to_ns(struct pwm_chip *chip,
return cnt * fin_ns * (channel->pre_div + 1);
}
-static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct meson_pwm *meson = to_meson_pwm(chip);
struct meson_pwm_channel_data *channel_data;
@@ -327,7 +327,7 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
u32 value, tmp;
if (!state)
- return;
+ return 0;
channel = &meson->channels[pwm->hwpwm];
channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
@@ -357,6 +357,8 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->period = 0;
state->duty_cycle = 0;
}
+
+ return 0;
}
static const struct pwm_ops meson_pwm_ops = {
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index c605013e4114..692a06121b28 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -172,32 +172,33 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
-static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
+static int mtk_disp_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
u64 rate, period, high_width;
- u32 clk_div, con0, con1;
+ u32 clk_div, pwm_en, con0, con1;
int err;
err = clk_prepare_enable(mdp->clk_main);
if (err < 0) {
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
- return;
+ return err;
}
err = clk_prepare_enable(mdp->clk_mm);
if (err < 0) {
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
clk_disable_unprepare(mdp->clk_main);
- return;
+ return err;
}
rate = clk_get_rate(mdp->clk_main);
con0 = readl(mdp->base + mdp->data->con0);
con1 = readl(mdp->base + mdp->data->con1);
- state->enabled = !!(con0 & BIT(0));
+ pwm_en = readl(mdp->base + DISP_PWM_EN);
+ state->enabled = !!(pwm_en & mdp->data->enable_mask);
clk_div = FIELD_GET(PWM_CLKDIV_MASK, con0);
period = FIELD_GET(PWM_PERIOD_MASK, con1);
/*
@@ -211,6 +212,8 @@ static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
state->polarity = PWM_POLARITY_NORMAL;
clk_disable_unprepare(mdp->clk_mm);
clk_disable_unprepare(mdp->clk_main);
+
+ return 0;
}
static const struct pwm_ops mtk_disp_pwm_ops = {
diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c
index f230c10d28bb..3ed5a48ca581 100644
--- a/drivers/pwm/pwm-pca9685.c
+++ b/drivers/pwm/pwm-pca9685.c
@@ -431,8 +431,8 @@ static int pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return ret;
}
-static void pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct pca9685 *pca = to_pca(chip);
unsigned long long duty;
@@ -458,12 +458,14 @@ static void pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
*/
state->duty_cycle = 0;
state->enabled = false;
- return;
+ return 0;
}
state->enabled = true;
duty = pca9685_pwm_get_duty(pca, pwm->hwpwm);
state->duty_cycle = DIV_ROUND_DOWN_ULL(duty * state->period, PCA9685_COUNTER_RANGE);
+
+ return 0;
}
static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
@@ -513,8 +515,7 @@ static const struct regmap_config pca9685_regmap_i2c_config = {
.cache_type = REGCACHE_NONE,
};
-static int pca9685_pwm_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int pca9685_pwm_probe(struct i2c_client *client)
{
struct pca9685 *pca;
unsigned int reg;
@@ -664,7 +665,7 @@ static struct i2c_driver pca9685_i2c_driver = {
.of_match_table = of_match_ptr(pca9685_dt_ids),
.pm = &pca9685_pwm_pm,
},
- .probe = pca9685_pwm_probe,
+ .probe_new = pca9685_pwm_probe,
.remove = pca9685_pwm_remove,
.id_table = pca9685_id,
};
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index 0bcaa58c6a91..46ed668bd141 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -6,6 +6,13 @@
*
* 2008-02-13 initial version
* eric miao <eric.miao@marvell.com>
+ *
+ * Links to reference manuals for some of the supported PWM chips can be found
+ * in Documentation/arm/marvell.rst.
+ *
+ * Limitations:
+ * - When PWM is stopped, the current PWM period stops abruptly at the next
+ * input clock (PWMCR_SD is set) and the output is driven to inactive.
*/
#include <linux/module.h>
@@ -64,7 +71,6 @@ static int pxa_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long long c;
unsigned long period_cycles, prescale, pv, dc;
unsigned long offset;
- int rc;
offset = pwm->hwpwm ? 0x10 : 0;
@@ -86,56 +92,42 @@ static int pxa_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
else
dc = mul_u64_u64_div_u64(pv + 1, duty_ns, period_ns);
- /* NOTE: the clock to PWM has to be enabled first
- * before writing to the registers
- */
- rc = clk_prepare_enable(pc->clk);
- if (rc < 0)
- return rc;
-
- writel(prescale, pc->mmio_base + offset + PWMCR);
+ writel(prescale | PWMCR_SD, pc->mmio_base + offset + PWMCR);
writel(dc, pc->mmio_base + offset + PWMDCR);
writel(pv, pc->mmio_base + offset + PWMPCR);
- clk_disable_unprepare(pc->clk);
return 0;
}
-static int pxa_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
- struct pxa_pwm_chip *pc = to_pxa_pwm_chip(chip);
-
- return clk_prepare_enable(pc->clk);
-}
-
-static void pxa_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
- struct pxa_pwm_chip *pc = to_pxa_pwm_chip(chip);
-
- clk_disable_unprepare(pc->clk);
-}
-
static int pxa_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
+ struct pxa_pwm_chip *pc = to_pxa_pwm_chip(chip);
+ u64 duty_cycle;
int err;
if (state->polarity != PWM_POLARITY_NORMAL)
return -EINVAL;
- if (!state->enabled) {
- if (pwm->state.enabled)
- pxa_pwm_disable(chip, pwm);
+ err = clk_prepare_enable(pc->clk);
+ if (err)
+ return err;
- return 0;
- }
+ duty_cycle = state->enabled ? state->duty_cycle : 0;
- err = pxa_pwm_config(chip, pwm, state->duty_cycle, state->period);
- if (err)
+ err = pxa_pwm_config(chip, pwm, duty_cycle, state->period);
+ if (err) {
+ clk_disable_unprepare(pc->clk);
return err;
+ }
+
+ if (state->enabled && !pwm->state.enabled)
+ return 0;
+
+ clk_disable_unprepare(pc->clk);
- if (!pwm->state.enabled)
- return pxa_pwm_enable(chip, pwm);
+ if (!state->enabled && pwm->state.enabled)
+ clk_disable_unprepare(pc->clk);
return 0;
}
diff --git a/drivers/pwm/pwm-raspberrypi-poe.c b/drivers/pwm/pwm-raspberrypi-poe.c
index 6ff73029f367..2939b71a7ba7 100644
--- a/drivers/pwm/pwm-raspberrypi-poe.c
+++ b/drivers/pwm/pwm-raspberrypi-poe.c
@@ -82,9 +82,9 @@ static int raspberrypi_pwm_get_property(struct rpi_firmware *firmware,
return 0;
}
-static void raspberrypi_pwm_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
+static int raspberrypi_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct raspberrypi_pwm *rpipwm = raspberrypi_pwm_from_chip(chip);
@@ -93,6 +93,8 @@ static void raspberrypi_pwm_get_state(struct pwm_chip *chip,
RPI_PWM_MAX_DUTY);
state->enabled = !!(rpipwm->duty_cycle);
state->polarity = PWM_POLARITY_NORMAL;
+
+ return 0;
}
static int raspberrypi_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index a5af859217c1..7f084eb34092 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -57,9 +57,9 @@ static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
return container_of(c, struct rockchip_pwm_chip, chip);
}
-static void rockchip_pwm_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
+static int rockchip_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = pc->data->enable_conf;
@@ -70,11 +70,11 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
ret = clk_enable(pc->pclk);
if (ret)
- return;
+ return ret;
ret = clk_enable(pc->clk);
if (ret)
- return;
+ return ret;
clk_rate = clk_get_rate(pc->clk);
@@ -96,6 +96,8 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
clk_disable(pc->clk);
clk_disable(pc->pclk);
+
+ return 0;
}
static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
index 2d4fa5e5fdd4..62b6acc6373d 100644
--- a/drivers/pwm/pwm-sifive.c
+++ b/drivers/pwm/pwm-sifive.c
@@ -105,8 +105,8 @@ static void pwm_sifive_update_clock(struct pwm_sifive_ddata *ddata,
"New real_period = %u ns\n", ddata->real_period);
}
-static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct pwm_sifive_ddata *ddata = pwm_sifive_chip_to_ddata(chip);
u32 duty, val;
@@ -123,6 +123,8 @@ static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->duty_cycle =
(u64)duty * ddata->real_period >> PWM_SIFIVE_CMPWIDTH;
state->polarity = PWM_POLARITY_INVERSED;
+
+ return 0;
}
static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -204,8 +206,11 @@ static int pwm_sifive_clock_notifier(struct notifier_block *nb,
struct pwm_sifive_ddata *ddata =
container_of(nb, struct pwm_sifive_ddata, notifier);
- if (event == POST_RATE_CHANGE)
+ if (event == POST_RATE_CHANGE) {
+ mutex_lock(&ddata->lock);
pwm_sifive_update_clock(ddata, ndata->new_rate);
+ mutex_unlock(&ddata->lock);
+ }
return NOTIFY_OK;
}
diff --git a/drivers/pwm/pwm-sl28cpld.c b/drivers/pwm/pwm-sl28cpld.c
index 589aeaaa6ac8..e64900ad4ba1 100644
--- a/drivers/pwm/pwm-sl28cpld.c
+++ b/drivers/pwm/pwm-sl28cpld.c
@@ -87,9 +87,9 @@ struct sl28cpld_pwm {
#define sl28cpld_pwm_from_chip(_chip) \
container_of(_chip, struct sl28cpld_pwm, pwm_chip)
-static void sl28cpld_pwm_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
+static int sl28cpld_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct sl28cpld_pwm *priv = sl28cpld_pwm_from_chip(chip);
unsigned int reg;
@@ -115,6 +115,8 @@ static void sl28cpld_pwm_get_state(struct pwm_chip *chip,
* the PWM core.
*/
state->duty_cycle = min(state->duty_cycle, state->period);
+
+ return 0;
}
static int sl28cpld_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
diff --git a/drivers/pwm/pwm-sprd.c b/drivers/pwm/pwm-sprd.c
index 7004f55bbf11..d866ce345f97 100644
--- a/drivers/pwm/pwm-sprd.c
+++ b/drivers/pwm/pwm-sprd.c
@@ -65,8 +65,8 @@ static void sprd_pwm_write(struct sprd_pwm_chip *spc, u32 hwid,
writel_relaxed(val, spc->base + offset);
}
-static void sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct sprd_pwm_chip *spc =
container_of(chip, struct sprd_pwm_chip, chip);
@@ -83,7 +83,7 @@ static void sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
if (ret) {
dev_err(spc->dev, "failed to enable pwm%u clocks\n",
pwm->hwpwm);
- return;
+ return ret;
}
val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_ENABLE);
@@ -113,6 +113,8 @@ static void sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
/* Disable PWM clocks if the PWM channel is not in enable state. */
if (!state->enabled)
clk_bulk_disable_unprepare(SPRD_PWM_CHN_CLKS_NUM, chn->clks);
+
+ return 0;
}
static int sprd_pwm_config(struct sprd_pwm_chip *spc, struct pwm_device *pwm,
diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
index 3115abb3f52a..514ff58a4471 100644
--- a/drivers/pwm/pwm-stm32-lp.c
+++ b/drivers/pwm/pwm-stm32-lp.c
@@ -140,9 +140,8 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (reenable) {
/* Start LP timer in continuous mode */
- ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
- STM32_LPTIM_CNTSTRT,
- STM32_LPTIM_CNTSTRT);
+ ret = regmap_set_bits(priv->regmap, STM32_LPTIM_CR,
+ STM32_LPTIM_CNTSTRT);
if (ret) {
regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
goto err;
@@ -157,9 +156,9 @@ err:
return ret;
}
-static void stm32_pwm_lp_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
+static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip);
unsigned long rate = clk_get_rate(priv->clk);
@@ -185,6 +184,8 @@ static void stm32_pwm_lp_get_state(struct pwm_chip *chip,
tmp = prd - val;
tmp = (tmp << presc) * NSEC_PER_SEC;
state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
+
+ return 0;
}
static const struct pwm_ops stm32_pwm_lp_ops = {
diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index 794ca5b02968..21e4a34dfff3 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -115,14 +115,14 @@ static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm,
int ret;
/* Ensure registers have been updated, enable counter and capture */
- regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
+ regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG);
+ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
/* Use cc1 or cc3 DMA resp for PWM input channels 1 & 2 or 3 & 4 */
dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3;
ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E;
ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3;
- regmap_update_bits(priv->regmap, TIM_CCER, ccen, ccen);
+ regmap_set_bits(priv->regmap, TIM_CCER, ccen);
/*
* Timer DMA burst mode. Request 2 registers, 2 bursts, to get both
@@ -160,8 +160,8 @@ static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm,
}
stop:
- regmap_update_bits(priv->regmap, TIM_CCER, ccen, 0);
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
+ regmap_clear_bits(priv->regmap, TIM_CCER, ccen);
+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
return ret;
}
@@ -359,7 +359,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch,
regmap_write(priv->regmap, TIM_PSC, prescaler);
regmap_write(priv->regmap, TIM_ARR, prd - 1);
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
+ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE);
/* Calculate the duty cycles */
dty = prd * duty_ns;
@@ -377,7 +377,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch,
else
regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr);
- regmap_update_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE, TIM_BDTR_MOE);
+ regmap_set_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE);
return 0;
}
@@ -411,13 +411,13 @@ static int stm32_pwm_enable(struct stm32_pwm *priv, int ch)
if (priv->have_complementary_output)
mask |= TIM_CCER_CC1NE << (ch * 4);
- regmap_update_bits(priv->regmap, TIM_CCER, mask, mask);
+ regmap_set_bits(priv->regmap, TIM_CCER, mask);
/* Make sure that registers are updated */
- regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
+ regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG);
/* Enable controller */
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
+ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
return 0;
}
@@ -431,11 +431,11 @@ static void stm32_pwm_disable(struct stm32_pwm *priv, int ch)
if (priv->have_complementary_output)
mask |= TIM_CCER_CC1NE << (ch * 4);
- regmap_update_bits(priv->regmap, TIM_CCER, mask, 0);
+ regmap_clear_bits(priv->regmap, TIM_CCER, mask);
/* When all channels are disabled, we can disable the controller */
if (!active_channels(priv))
- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
clk_disable(priv->clk);
}
@@ -568,10 +568,9 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
* If complementary bit doesn't exist writing 1 will have no
* effect so we can detect it.
*/
- regmap_update_bits(priv->regmap,
- TIM_CCER, TIM_CCER_CC1NE, TIM_CCER_CC1NE);
+ regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE);
regmap_read(priv->regmap, TIM_CCER, &ccer);
- regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE, 0);
+ regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE);
priv->have_complementary_output = (ccer != 0);
}
@@ -585,10 +584,9 @@ static int stm32_pwm_detect_channels(struct stm32_pwm *priv)
* If channels enable bits don't exist writing 1 will have no
* effect so we can detect and count them.
*/
- regmap_update_bits(priv->regmap,
- TIM_CCER, TIM_CCER_CCXE, TIM_CCER_CCXE);
+ regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE);
regmap_read(priv->regmap, TIM_CCER, &ccer);
- regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE, 0);
+ regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE);
if (ccer & TIM_CCER_CC1E)
npwm++;
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index c8445b0a3339..b973da73e9ab 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -108,9 +108,9 @@ static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
writel(val, chip->base + offset);
}
-static void sun4i_pwm_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
+static int sun4i_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
u64 clk_rate, tmp;
@@ -118,6 +118,8 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
unsigned int prescaler;
clk_rate = clk_get_rate(sun4i_pwm->clk);
+ if (!clk_rate)
+ return -EINVAL;
val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
@@ -132,7 +134,7 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
state->duty_cycle = DIV_ROUND_UP_ULL(state->period, 2);
state->polarity = PWM_POLARITY_NORMAL;
state->enabled = true;
- return;
+ return 0;
}
if ((PWM_REG_PRESCAL(val, pwm->hwpwm) == PWM_PRESCAL_MASK) &&
@@ -142,7 +144,7 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
prescaler = prescaler_table[PWM_REG_PRESCAL(val, pwm->hwpwm)];
if (prescaler == 0)
- return;
+ return -EINVAL;
if (val & BIT_CH(PWM_ACT_STATE, pwm->hwpwm))
state->polarity = PWM_POLARITY_NORMAL;
@@ -162,6 +164,8 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_PRD(val);
state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
+
+ return 0;
}
static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
diff --git a/drivers/pwm/pwm-sunplus.c b/drivers/pwm/pwm-sunplus.c
index e776fd16512d..d6ebe9f03b35 100644
--- a/drivers/pwm/pwm-sunplus.c
+++ b/drivers/pwm/pwm-sunplus.c
@@ -124,8 +124,8 @@ static int sunplus_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
-static void sunplus_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int sunplus_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct sunplus_pwm *priv = to_sunplus_pwm(chip);
u32 mode0, dd_freq, duty;
@@ -155,6 +155,8 @@ static void sunplus_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
}
state->polarity = PWM_POLARITY_NORMAL;
+
+ return 0;
}
static const struct pwm_ops sunplus_pwm_ops = {
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index dad9978c9186..249dc0193297 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -145,8 +145,19 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
* source clock rate as required_clk_rate, PWM controller will
* be able to configure the requested period.
*/
- required_clk_rate =
- (NSEC_PER_SEC / period_ns) << PWM_DUTY_WIDTH;
+ required_clk_rate = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC << PWM_DUTY_WIDTH,
+ period_ns);
+
+ if (required_clk_rate > clk_round_rate(pc->clk, required_clk_rate))
+ /*
+ * required_clk_rate is a lower bound for the input
+ * rate; for lower rates there is no value for PWM_SCALE
+ * that yields a period less than or equal to the
+ * requested period. Hence, for lower rates, double the
+ * required_clk_rate to get a clock rate that can meet
+ * the requested period.
+ */
+ required_clk_rate *= 2;
err = dev_pm_opp_set_rate(pc->dev, required_clk_rate);
if (err < 0)
diff --git a/drivers/pwm/pwm-visconti.c b/drivers/pwm/pwm-visconti.c
index 927c4cbb1daf..e3fb79b3e2a7 100644
--- a/drivers/pwm/pwm-visconti.c
+++ b/drivers/pwm/pwm-visconti.c
@@ -103,8 +103,8 @@ static int visconti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
-static void visconti_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int visconti_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
struct visconti_pwm_chip *priv = visconti_pwm_from_chip(chip);
u32 period, duty, pwmc0, pwmc0_clk;
@@ -122,6 +122,8 @@ static void visconti_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm
state->polarity = PWM_POLARITY_NORMAL;
state->enabled = true;
+
+ return 0;
}
static const struct pwm_ops visconti_pwm_ops = {
diff --git a/drivers/pwm/pwm-xilinx.c b/drivers/pwm/pwm-xilinx.c
index 4dab2b86c427..f7a50fdcd9a5 100644
--- a/drivers/pwm/pwm-xilinx.c
+++ b/drivers/pwm/pwm-xilinx.c
@@ -169,9 +169,9 @@ static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
return 0;
}
-static void xilinx_pwm_get_state(struct pwm_chip *chip,
- struct pwm_device *unused,
- struct pwm_state *state)
+static int xilinx_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *unused,
+ struct pwm_state *state)
{
struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
u32 tlr0, tlr1, tcsr0, tcsr1;
@@ -191,6 +191,8 @@ static void xilinx_pwm_get_state(struct pwm_chip *chip,
*/
if (state->period == state->duty_cycle)
state->duty_cycle = 0;
+
+ return 0;
}
static const struct pwm_ops xilinx_pwm_ops = {
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 166019786653..a850e9f486dd 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -352,6 +352,19 @@ config TI_K3_R5_REMOTEPROC
It's safe to say N here if you're not interested in utilizing
a slave processor.
+config XLNX_R5_REMOTEPROC
+ tristate "Xilinx R5 remoteproc support"
+ depends on PM && ARCH_ZYNQMP
+ select ZYNQMP_FIRMWARE
+ select RPMSG_VIRTIO
+ select MAILBOX
+ select ZYNQMP_IPI_MBOX
+ help
+ Say y or m here to support Xilinx R5 remote processors via the remote
+ processor framework.
+
+ It's safe to say N if not interested in using RPU r5f cores.
+
endif # REMOTEPROC
endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 5478c7cb9e07..91314a9b43ce 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -38,3 +38,4 @@ obj-$(CONFIG_ST_SLIM_REMOTEPROC) += st_slim_rproc.o
obj-$(CONFIG_STM32_RPROC) += stm32_rproc.o
obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
obj-$(CONFIG_TI_K3_R5_REMOTEPROC) += ti_k3_r5_remoteproc.o
+obj-$(CONFIG_XLNX_R5_REMOTEPROC) += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
index 899aa8dd12f0..95da1cbefacf 100644
--- a/drivers/remoteproc/imx_dsp_rproc.c
+++ b/drivers/remoteproc/imx_dsp_rproc.c
@@ -347,9 +347,6 @@ static int imx_dsp_rproc_stop(struct rproc *rproc)
struct device *dev = rproc->dev.parent;
int ret = 0;
- /* Make sure work is finished */
- flush_work(&priv->rproc_work);
-
if (rproc->state == RPROC_CRASHED) {
priv->flags &= ~REMOTE_IS_READY;
return 0;
@@ -432,9 +429,18 @@ static void imx_dsp_rproc_vq_work(struct work_struct *work)
{
struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
rproc_work);
+ struct rproc *rproc = priv->rproc;
+
+ mutex_lock(&rproc->lock);
+
+ if (rproc->state != RPROC_RUNNING)
+ goto unlock_mutex;
rproc_vq_interrupt(priv->rproc, 0);
rproc_vq_interrupt(priv->rproc, 1);
+
+unlock_mutex:
+ mutex_unlock(&rproc->lock);
}
/**
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 7cc4fd207e2d..9fc978e0393c 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -3,9 +3,11 @@
* Copyright (c) 2017 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
*/
+#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/firmware/imx/sci.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mailbox_client.h>
@@ -15,6 +17,7 @@
#include <linux/of_reserved_mem.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
#include <linux/regmap.h>
#include <linux/remoteproc.h>
#include <linux/workqueue.h>
@@ -59,6 +62,8 @@
#define IMX_SIP_RPROC_STARTED 0x01
#define IMX_SIP_RPROC_STOP 0x02
+#define IMX_SC_IRQ_GROUP_REBOOTED 5
+
/**
* struct imx_rproc_mem - slim internal memory structure
* @cpu_addr: MPU virtual address of the memory region
@@ -71,10 +76,17 @@ struct imx_rproc_mem {
size_t size;
};
-/* att flags */
+/* att flags: lower 16 bits specifying core, higher 16 bits for flags */
/* M4 own area. Can be mapped at probe */
-#define ATT_OWN BIT(1)
-#define ATT_IOMEM BIT(2)
+#define ATT_OWN BIT(31)
+#define ATT_IOMEM BIT(30)
+
+#define ATT_CORE_MASK 0xffff
+#define ATT_CORE(I) BIT((I))
+
+static int imx_rproc_xtr_mbox_init(struct rproc *rproc);
+static void imx_rproc_free_mbox(struct rproc *rproc);
+static int imx_rproc_detach_pd(struct rproc *rproc);
struct imx_rproc {
struct device *dev;
@@ -89,6 +101,15 @@ struct imx_rproc {
struct work_struct rproc_work;
struct workqueue_struct *workqueue;
void __iomem *rsc_table;
+ struct imx_sc_ipc *ipc_handle;
+ struct notifier_block rproc_nb;
+ u32 rproc_pt; /* partition id */
+ u32 rsrc_id; /* resource id */
+ u32 entry; /* cpu start address */
+ int num_pd;
+ u32 core_index;
+ struct device **pd_dev;
+ struct device_link **pd_dev_link;
};
static const struct imx_rproc_att imx_rproc_att_imx93[] = {
@@ -113,8 +134,33 @@ static const struct imx_rproc_att imx_rproc_att_imx93[] = {
{ 0x80000000, 0x80000000, 0x10000000, 0 },
{ 0x90000000, 0x80000000, 0x10000000, 0 },
- { 0xC0000000, 0xa0000000, 0x10000000, 0 },
- { 0xD0000000, 0xa0000000, 0x10000000, 0 },
+ { 0xC0000000, 0xC0000000, 0x10000000, 0 },
+ { 0xD0000000, 0xC0000000, 0x10000000, 0 },
+};
+
+static const struct imx_rproc_att imx_rproc_att_imx8qm[] = {
+ /* dev addr , sys addr , size , flags */
+ { 0x08000000, 0x08000000, 0x10000000, 0},
+ /* TCML */
+ { 0x1FFE0000, 0x34FE0000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(0)},
+ { 0x1FFE0000, 0x38FE0000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(1)},
+ /* TCMU */
+ { 0x20000000, 0x35000000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(0)},
+ { 0x20000000, 0x39000000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(1)},
+ /* DDR (Data) */
+ { 0x80000000, 0x80000000, 0x60000000, 0 },
+};
+
+static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
+ { 0x08000000, 0x08000000, 0x10000000, 0 },
+ /* TCML/U */
+ { 0x1FFE0000, 0x34FE0000, 0x00040000, ATT_OWN | ATT_IOMEM },
+ /* OCRAM(Low 96KB) */
+ { 0x21000000, 0x00100000, 0x00018000, 0 },
+ /* OCRAM */
+ { 0x21100000, 0x00100000, 0x00040000, 0 },
+ /* DDR (Data) */
+ { 0x80000000, 0x80000000, 0x60000000, 0 },
};
static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
@@ -255,6 +301,18 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
.method = IMX_RPROC_MMIO,
};
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = {
+ .att = imx_rproc_att_imx8qm,
+ .att_size = ARRAY_SIZE(imx_rproc_att_imx8qm),
+ .method = IMX_RPROC_SCU_API,
+};
+
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
+ .att = imx_rproc_att_imx8qxp,
+ .att_size = ARRAY_SIZE(imx_rproc_att_imx8qxp),
+ .method = IMX_RPROC_SCU_API,
+};
+
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
.att = imx_rproc_att_imx8ulp,
.att_size = ARRAY_SIZE(imx_rproc_att_imx8ulp),
@@ -301,6 +359,10 @@ static int imx_rproc_start(struct rproc *rproc)
struct arm_smccc_res res;
int ret;
+ ret = imx_rproc_xtr_mbox_init(rproc);
+ if (ret)
+ return ret;
+
switch (dcfg->method) {
case IMX_RPROC_MMIO:
ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
@@ -310,6 +372,9 @@ static int imx_rproc_start(struct rproc *rproc)
arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
ret = res.a0;
break;
+ case IMX_RPROC_SCU_API:
+ ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry);
+ break;
default:
return -EOPNOTSUPP;
}
@@ -339,12 +404,17 @@ static int imx_rproc_stop(struct rproc *rproc)
if (res.a1)
dev_info(dev, "Not in wfi, force stopped\n");
break;
+ case IMX_RPROC_SCU_API:
+ ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry);
+ break;
default:
return -EOPNOTSUPP;
}
if (ret)
dev_err(dev, "Failed to stop remote core\n");
+ else
+ imx_rproc_free_mbox(rproc);
return ret;
}
@@ -359,6 +429,17 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
for (i = 0; i < dcfg->att_size; i++) {
const struct imx_rproc_att *att = &dcfg->att[i];
+ /*
+ * Ignore entries not belong to current core:
+ * i.MX8QM has dual general M4_[0,1] cores, M4_0's own entries
+ * has "ATT_CORE(0) & BIT(0)" true, M4_1's own entries has
+ * "ATT_CORE(1) & BIT(1)" true.
+ */
+ if (att->flags & ATT_CORE_MASK) {
+ if (!((BIT(priv->core_index)) & (att->flags & ATT_CORE_MASK)))
+ continue;
+ }
+
if (da >= att->da && da + len < att->da + att->size) {
unsigned int offset = da - att->da;
@@ -519,6 +600,22 @@ static void imx_rproc_kick(struct rproc *rproc, int vqid)
static int imx_rproc_attach(struct rproc *rproc)
{
+ return imx_rproc_xtr_mbox_init(rproc);
+}
+
+static int imx_rproc_detach(struct rproc *rproc)
+{
+ struct imx_rproc *priv = rproc->priv;
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+
+ if (dcfg->method != IMX_RPROC_SCU_API)
+ return -EOPNOTSUPP;
+
+ if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id))
+ return -EOPNOTSUPP;
+
+ imx_rproc_free_mbox(rproc);
+
return 0;
}
@@ -537,6 +634,7 @@ static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc
static const struct rproc_ops imx_rproc_ops = {
.prepare = imx_rproc_prepare,
.attach = imx_rproc_attach,
+ .detach = imx_rproc_detach,
.start = imx_rproc_start,
.stop = imx_rproc_stop,
.kick = imx_rproc_kick,
@@ -647,6 +745,18 @@ static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
struct device *dev = priv->dev;
struct mbox_client *cl;
+ /*
+ * stop() and detach() will free the mbox channels, so need
+ * to request mbox channels in start() and attach().
+ *
+ * Because start() and attach() not able to handle mbox defer
+ * probe, imx_rproc_xtr_mbox_init is also called in probe().
+ * The check is to avoid request mbox again when start() or
+ * attach() after probe() returns success.
+ */
+ if (priv->tx_ch && priv->rx_ch)
+ return 0;
+
if (!of_get_property(dev->of_node, "mbox-names", NULL))
return 0;
@@ -676,8 +786,119 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
{
struct imx_rproc *priv = rproc->priv;
- mbox_free_channel(priv->tx_ch);
- mbox_free_channel(priv->rx_ch);
+ if (priv->tx_ch) {
+ mbox_free_channel(priv->tx_ch);
+ priv->tx_ch = NULL;
+ }
+
+ if (priv->rx_ch) {
+ mbox_free_channel(priv->rx_ch);
+ priv->rx_ch = NULL;
+ }
+}
+
+static void imx_rproc_put_scu(struct rproc *rproc)
+{
+ struct imx_rproc *priv = rproc->priv;
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+
+ if (dcfg->method != IMX_RPROC_SCU_API)
+ return;
+
+ if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
+ imx_rproc_detach_pd(rproc);
+ return;
+ }
+
+ imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), false);
+ imx_scu_irq_unregister_notifier(&priv->rproc_nb);
+}
+
+static int imx_rproc_partition_notify(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+ struct imx_rproc *priv = container_of(nb, struct imx_rproc, rproc_nb);
+
+ /* Ignore other irqs */
+ if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group == IMX_SC_IRQ_GROUP_REBOOTED)))
+ return 0;
+
+ rproc_report_crash(priv->rproc, RPROC_WATCHDOG);
+
+ pr_info("Partition%d reset!\n", priv->rproc_pt);
+
+ return 0;
+}
+
+static int imx_rproc_attach_pd(struct imx_rproc *priv)
+{
+ struct device *dev = priv->dev;
+ int ret, i;
+
+ /*
+ * If there is only one power-domain entry, the platform driver framework
+ * will handle it, no need handle it in this driver.
+ */
+ priv->num_pd = of_count_phandle_with_args(dev->of_node, "power-domains",
+ "#power-domain-cells");
+ if (priv->num_pd <= 1)
+ return 0;
+
+ priv->pd_dev = devm_kmalloc_array(dev, priv->num_pd, sizeof(*priv->pd_dev), GFP_KERNEL);
+ if (!priv->pd_dev)
+ return -ENOMEM;
+
+ priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_pd, sizeof(*priv->pd_dev_link),
+ GFP_KERNEL);
+
+ if (!priv->pd_dev_link)
+ return -ENOMEM;
+
+ for (i = 0; i < priv->num_pd; i++) {
+ priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
+ if (IS_ERR(priv->pd_dev[i])) {
+ ret = PTR_ERR(priv->pd_dev[i]);
+ goto detach_pd;
+ }
+
+ priv->pd_dev_link[i] = device_link_add(dev, priv->pd_dev[i], DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
+ if (!priv->pd_dev_link[i]) {
+ dev_pm_domain_detach(priv->pd_dev[i], false);
+ ret = -EINVAL;
+ goto detach_pd;
+ }
+ }
+
+ return 0;
+
+detach_pd:
+ while (--i >= 0) {
+ device_link_del(priv->pd_dev_link[i]);
+ dev_pm_domain_detach(priv->pd_dev[i], false);
+ }
+
+ return ret;
+}
+
+static int imx_rproc_detach_pd(struct rproc *rproc)
+{
+ struct imx_rproc *priv = rproc->priv;
+ int i;
+
+ /*
+ * If there is only one power-domain entry, the platform driver framework
+ * will handle it, no need handle it in this driver.
+ */
+ if (priv->num_pd <= 1)
+ return 0;
+
+ for (i = 0; i < priv->num_pd; i++) {
+ device_link_del(priv->pd_dev_link[i]);
+ dev_pm_domain_detach(priv->pd_dev[i], false);
+ }
+
+ return 0;
}
static int imx_rproc_detect_mode(struct imx_rproc *priv)
@@ -689,6 +910,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
struct arm_smccc_res res;
int ret;
u32 val;
+ u8 pt;
switch (dcfg->method) {
case IMX_RPROC_NONE:
@@ -699,6 +921,61 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
if (res.a0)
priv->rproc->state = RPROC_DETACHED;
return 0;
+ case IMX_RPROC_SCU_API:
+ ret = imx_scu_get_handle(&priv->ipc_handle);
+ if (ret)
+ return ret;
+ ret = of_property_read_u32(dev->of_node, "fsl,resource-id", &priv->rsrc_id);
+ if (ret) {
+ dev_err(dev, "No fsl,resource-id property\n");
+ return ret;
+ }
+
+ if (priv->rsrc_id == IMX_SC_R_M4_1_PID0)
+ priv->core_index = 1;
+ else
+ priv->core_index = 0;
+
+ /*
+ * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
+ * and Linux could only do IPC with Mcore and nothing else.
+ */
+ if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
+ if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry))
+ return -EINVAL;
+
+ return imx_rproc_attach_pd(priv);
+ }
+
+ priv->rproc->state = RPROC_DETACHED;
+ priv->rproc->recovery_disabled = false;
+ rproc_set_feature(priv->rproc, RPROC_FEAT_ATTACH_ON_RECOVERY);
+
+ /* Get partition id and enable irq in SCFW */
+ ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc_id, &pt);
+ if (ret) {
+ dev_err(dev, "not able to get resource owner\n");
+ return ret;
+ }
+
+ priv->rproc_pt = pt;
+ priv->rproc_nb.notifier_call = imx_rproc_partition_notify;
+
+ ret = imx_scu_irq_register_notifier(&priv->rproc_nb);
+ if (ret) {
+ dev_err(dev, "register scu notifier failed, %d\n", ret);
+ return ret;
+ }
+
+ ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt),
+ true);
+ if (ret) {
+ imx_scu_irq_unregister_notifier(&priv->rproc_nb);
+ dev_err(dev, "Enable irq failed, %d\n", ret);
+ return ret;
+ }
+
+ return 0;
default:
break;
}
@@ -803,7 +1080,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
ret = imx_rproc_clk_enable(priv);
if (ret)
- goto err_put_mbox;
+ goto err_put_scu;
INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
@@ -820,6 +1097,8 @@ static int imx_rproc_probe(struct platform_device *pdev)
err_put_clk:
clk_disable_unprepare(priv->clk);
+err_put_scu:
+ imx_rproc_put_scu(rproc);
err_put_mbox:
imx_rproc_free_mbox(rproc);
err_put_wkq:
@@ -837,6 +1116,7 @@ static int imx_rproc_remove(struct platform_device *pdev)
clk_disable_unprepare(priv->clk);
rproc_del(rproc);
+ imx_rproc_put_scu(rproc);
imx_rproc_free_mbox(rproc);
destroy_workqueue(priv->workqueue);
rproc_free(rproc);
@@ -852,6 +1132,8 @@ static const struct of_device_id imx_rproc_of_match[] = {
{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
+ { .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
+ { .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
{ .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
{},
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 6afd0941e552..dc6f07ca8341 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -449,6 +449,7 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
}
ret = of_address_to_resource(node, 0, &r);
+ of_node_put(node);
if (ret)
return ret;
@@ -556,6 +557,7 @@ static int adsp_probe(struct platform_device *pdev)
detach_proxy_pds:
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
free_rproc:
+ device_init_wakeup(adsp->dev, false);
rproc_free(rproc);
return ret;
@@ -572,6 +574,8 @@ static int adsp_remove(struct platform_device *pdev)
qcom_remove_sysmon_subdev(adsp->sysmon);
qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
+ adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
+ device_init_wakeup(adsp->dev, false);
rproc_free(adsp->rproc);
return 0;
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
index bb0947f7770e..ba24d745b2d6 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -351,7 +351,7 @@ static int q6v5_wcss_qcs404_power_on(struct q6v5_wcss *wcss)
if (ret) {
dev_err(wcss->dev,
"xo cbcr enabling timed out (rc:%d)\n", ret);
- return ret;
+ goto disable_xo_cbcr_clk;
}
writel(0, wcss->reg_base + Q6SS_CGC_OVERRIDE);
@@ -417,6 +417,7 @@ disable_sleep_cbcr_clk:
val = readl(wcss->reg_base + Q6SS_SLEEP_CBCR);
val &= ~Q6SS_CLK_ENABLE;
writel(val, wcss->reg_base + Q6SS_SLEEP_CBCR);
+disable_xo_cbcr_clk:
val = readl(wcss->reg_base + Q6SS_XO_CBCR);
val &= ~Q6SS_CLK_ENABLE;
writel(val, wcss->reg_base + Q6SS_XO_CBCR);
@@ -827,6 +828,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,
int ret;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
+ if (!res)
+ return -EINVAL;
+
wcss->reg_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!wcss->reg_base)
diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
index 57dde2a69b9d..85393d5eb005 100644
--- a/drivers/remoteproc/qcom_sysmon.c
+++ b/drivers/remoteproc/qcom_sysmon.c
@@ -190,7 +190,7 @@ struct ssctl_shutdown_resp {
struct qmi_response_type_v01 resp;
};
-static struct qmi_elem_info ssctl_shutdown_resp_ei[] = {
+static const struct qmi_elem_info ssctl_shutdown_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
@@ -211,7 +211,7 @@ struct ssctl_subsys_event_req {
u32 evt_driven;
};
-static struct qmi_elem_info ssctl_subsys_event_req_ei[] = {
+static const struct qmi_elem_info ssctl_subsys_event_req_ei[] = {
{
.data_type = QMI_DATA_LEN,
.elem_len = 1,
@@ -269,7 +269,7 @@ struct ssctl_subsys_event_resp {
struct qmi_response_type_v01 resp;
};
-static struct qmi_elem_info ssctl_subsys_event_resp_ei[] = {
+static const struct qmi_elem_info ssctl_subsys_event_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
@@ -283,7 +283,7 @@ static struct qmi_elem_info ssctl_subsys_event_resp_ei[] = {
{}
};
-static struct qmi_elem_info ssctl_shutdown_ind_ei[] = {
+static const struct qmi_elem_info ssctl_shutdown_ind_ei[] = {
{}
};
@@ -652,7 +652,9 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
if (sysmon->shutdown_irq != -ENODATA) {
dev_err(sysmon->dev,
"failed to retrieve shutdown-ack IRQ\n");
- return ERR_PTR(sysmon->shutdown_irq);
+ ret = sysmon->shutdown_irq;
+ kfree(sysmon);
+ return ERR_PTR(ret);
}
} else {
ret = devm_request_threaded_irq(sysmon->dev,
@@ -663,6 +665,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
if (ret) {
dev_err(sysmon->dev,
"failed to acquire shutdown-ack IRQ\n");
+ kfree(sysmon);
return ERR_PTR(ret);
}
}
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 8768cb64f560..1cd4815a6dd1 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -509,7 +509,13 @@ static int rproc_handle_vdev(struct rproc *rproc, void *ptr,
rvdev_data.rsc_offset = offset;
rvdev_data.rsc = rsc;
- pdev = platform_device_register_data(dev, "rproc-virtio", rvdev_data.index, &rvdev_data,
+ /*
+ * When there is more than one remote processor, rproc->nb_vdev number is
+ * same for each separate instances of "rproc". If rvdev_data.index is used
+ * as device id, then we get duplication in sysfs, so need to use
+ * PLATFORM_DEVID_AUTO to auto select device id.
+ */
+ pdev = platform_device_register_data(dev, "rproc-virtio", PLATFORM_DEVID_AUTO, &rvdev_data,
sizeof(rvdev_data));
if (IS_ERR(pdev)) {
dev_err(dev, "failed to create rproc-virtio device\n");
@@ -1862,12 +1868,18 @@ static void rproc_crash_handler_work(struct work_struct *work)
mutex_lock(&rproc->lock);
- if (rproc->state == RPROC_CRASHED || rproc->state == RPROC_OFFLINE) {
+ if (rproc->state == RPROC_CRASHED) {
/* handle only the first crash detected */
mutex_unlock(&rproc->lock);
return;
}
+ if (rproc->state == RPROC_OFFLINE) {
+ /* Don't recover if the remote processor was stopped */
+ mutex_unlock(&rproc->lock);
+ goto out;
+ }
+
rproc->state = RPROC_CRASHED;
dev_err(dev, "handling crash #%u in %s\n", ++rproc->crash_cnt,
rproc->name);
@@ -1877,6 +1889,7 @@ static void rproc_crash_handler_work(struct work_struct *work)
if (!rproc->recovery_disabled)
rproc_trigger_recovery(rproc);
+out:
pm_relax(rproc->dev.parent);
}
@@ -2106,7 +2119,7 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
rcu_read_lock();
list_for_each_entry_rcu(r, &rproc_list, node) {
- if (r->dev.parent && r->dev.parent->of_node == np) {
+ if (r->dev.parent && device_match_of_node(r->dev.parent, np)) {
/* prevent underlying implementation from being removed */
if (!try_module_get(r->dev.parent->driver->owner)) {
dev_err(&r->dev, "can't get owner\n");
diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
new file mode 100644
index 000000000000..2db57d394155
--- /dev/null
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -0,0 +1,1067 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ZynqMP R5 Remote Processor driver
+ *
+ */
+
+#include <dt-bindings/power/xlnx-zynqmp-power.h>
+#include <linux/dma-mapping.h>
+#include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/slab.h>
+
+#include "remoteproc_internal.h"
+
+/*
+ * settings for RPU cluster mode which
+ * reflects possible values of xlnx,cluster-mode dt-property
+ */
+enum zynqmp_r5_cluster_mode {
+ SPLIT_MODE = 0, /* When cores run as separate processor */
+ LOCKSTEP_MODE = 1, /* cores execute same code in lockstep,clk-for-clk */
+ SINGLE_CPU_MODE = 2, /* core0 is held in reset and only core1 runs */
+};
+
+/**
+ * struct mem_bank_data - Memory Bank description
+ *
+ * @addr: Start address of memory bank
+ * @size: Size of Memory bank
+ * @pm_domain_id: Power-domains id of memory bank for firmware to turn on/off
+ * @bank_name: name of the bank for remoteproc framework
+ */
+struct mem_bank_data {
+ phys_addr_t addr;
+ size_t size;
+ u32 pm_domain_id;
+ char *bank_name;
+};
+
+/*
+ * Hardcoded TCM bank values. This will be removed once TCM bindings are
+ * accepted for system-dt specifications and upstreamed in linux kernel
+ */
+static const struct mem_bank_data zynqmp_tcm_banks[] = {
+ {0xffe00000UL, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
+ {0xffe20000UL, 0x10000UL, PD_R5_0_BTCM, "btcm0"},
+ {0xffe90000UL, 0x10000UL, PD_R5_1_ATCM, "atcm1"},
+ {0xffeb0000UL, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
+};
+
+/**
+ * struct zynqmp_r5_core
+ *
+ * @dev: device of RPU instance
+ * @np: device node of RPU instance
+ * @tcm_bank_count: number TCM banks accessible to this RPU
+ * @tcm_banks: array of each TCM bank data
+ * @rmem_count: Number of reserved mem regions
+ * @rmem: reserved memory region nodes from device tree
+ * @rproc: rproc handle
+ * @pm_domain_id: RPU CPU power domain id
+ */
+struct zynqmp_r5_core {
+ struct device *dev;
+ struct device_node *np;
+ int tcm_bank_count;
+ struct mem_bank_data **tcm_banks;
+ int rmem_count;
+ struct reserved_mem **rmem;
+ struct rproc *rproc;
+ u32 pm_domain_id;
+};
+
+/**
+ * struct zynqmp_r5_cluster
+ *
+ * @dev: r5f subsystem cluster device node
+ * @mode: cluster mode of type zynqmp_r5_cluster_mode
+ * @core_count: number of r5 cores used for this cluster mode
+ * @r5_cores: Array of pointers pointing to r5 core
+ */
+struct zynqmp_r5_cluster {
+ struct device *dev;
+ enum zynqmp_r5_cluster_mode mode;
+ int core_count;
+ struct zynqmp_r5_core **r5_cores;
+};
+
+/*
+ * zynqmp_r5_set_mode()
+ *
+ * set RPU cluster and TCM operation mode
+ *
+ * @r5_core: pointer to zynqmp_r5_core type object
+ * @fw_reg_val: value expected by firmware to configure RPU cluster mode
+ * @tcm_mode: value expected by fw to configure TCM mode (lockstep or split)
+ *
+ * Return: 0 for success and < 0 for failure
+ */
+static int zynqmp_r5_set_mode(struct zynqmp_r5_core *r5_core,
+ enum rpu_oper_mode fw_reg_val,
+ enum rpu_tcm_comb tcm_mode)
+{
+ int ret;
+
+ ret = zynqmp_pm_set_rpu_mode(r5_core->pm_domain_id, fw_reg_val);
+ if (ret < 0) {
+ dev_err(r5_core->dev, "failed to set RPU mode\n");
+ return ret;
+ }
+
+ ret = zynqmp_pm_set_tcm_config(r5_core->pm_domain_id, tcm_mode);
+ if (ret < 0)
+ dev_err(r5_core->dev, "failed to configure TCM\n");
+
+ return ret;
+}
+
+/*
+ * zynqmp_r5_rproc_start()
+ * @rproc: single R5 core's corresponding rproc instance
+ *
+ * Start R5 Core from designated boot address.
+ *
+ * return 0 on success, otherwise non-zero value on failure
+ */
+static int zynqmp_r5_rproc_start(struct rproc *rproc)
+{
+ struct zynqmp_r5_core *r5_core = rproc->priv;
+ enum rpu_boot_mem bootmem;
+ int ret;
+
+ /*
+ * The exception vector pointers (EVP) refer to the base-address of
+ * exception vectors (for reset, IRQ, FIQ, etc). The reset-vector
+ * starts at the base-address and subsequent vectors are on 4-byte
+ * boundaries.
+ *
+ * Exception vectors can start either from 0x0000_0000 (LOVEC) or
+ * from 0xFFFF_0000 (HIVEC) which is mapped in the OCM (On-Chip Memory)
+ *
+ * Usually firmware will put Exception vectors at LOVEC.
+ *
+ * It is not recommend that you change the exception vector.
+ * Changing the EVP to HIVEC will result in increased interrupt latency
+ * and jitter. Also, if the OCM is secured and the Cortex-R5F processor
+ * is non-secured, then the Cortex-R5F processor cannot access the
+ * HIVEC exception vectors in the OCM.
+ */
+ bootmem = (rproc->bootaddr >= 0xFFFC0000) ?
+ PM_RPU_BOOTMEM_HIVEC : PM_RPU_BOOTMEM_LOVEC;
+
+ dev_dbg(r5_core->dev, "RPU boot addr 0x%llx from %s.", rproc->bootaddr,
+ bootmem == PM_RPU_BOOTMEM_HIVEC ? "OCM" : "TCM");
+
+ ret = zynqmp_pm_request_wake(r5_core->pm_domain_id, 1,
+ bootmem, ZYNQMP_PM_REQUEST_ACK_NO);
+ if (ret)
+ dev_err(r5_core->dev,
+ "failed to start RPU = 0x%x\n", r5_core->pm_domain_id);
+ return ret;
+}
+
+/*
+ * zynqmp_r5_rproc_stop()
+ * @rproc: single R5 core's corresponding rproc instance
+ *
+ * Power down R5 Core.
+ *
+ * return 0 on success, otherwise non-zero value on failure
+ */
+static int zynqmp_r5_rproc_stop(struct rproc *rproc)
+{
+ struct zynqmp_r5_core *r5_core = rproc->priv;
+ int ret;
+
+ ret = zynqmp_pm_force_pwrdwn(r5_core->pm_domain_id,
+ ZYNQMP_PM_REQUEST_ACK_BLOCKING);
+ if (ret)
+ dev_err(r5_core->dev, "failed to stop remoteproc RPU %d\n", ret);
+
+ return ret;
+}
+
+/*
+ * zynqmp_r5_mem_region_map()
+ * @rproc: single R5 core's corresponding rproc instance
+ * @mem: mem descriptor to map reserved memory-regions
+ *
+ * Callback to map va for memory-region's carveout.
+ *
+ * return 0 on success, otherwise non-zero value on failure
+ */
+static int zynqmp_r5_mem_region_map(struct rproc *rproc,
+ struct rproc_mem_entry *mem)
+{
+ void __iomem *va;
+
+ va = ioremap_wc(mem->dma, mem->len);
+ if (IS_ERR_OR_NULL(va))
+ return -ENOMEM;
+
+ mem->va = (void *)va;
+
+ return 0;
+}
+
+/*
+ * zynqmp_r5_rproc_mem_unmap
+ * @rproc: single R5 core's corresponding rproc instance
+ * @mem: mem entry to unmap
+ *
+ * Unmap memory-region carveout
+ *
+ * return: always returns 0
+ */
+static int zynqmp_r5_mem_region_unmap(struct rproc *rproc,
+ struct rproc_mem_entry *mem)
+{
+ iounmap((void __iomem *)mem->va);
+ return 0;
+}
+
+/*
+ * add_mem_regions_carveout()
+ * @rproc: single R5 core's corresponding rproc instance
+ *
+ * Construct rproc mem carveouts from memory-region property nodes
+ *
+ * return 0 on success, otherwise non-zero value on failure
+ */
+static int add_mem_regions_carveout(struct rproc *rproc)
+{
+ struct rproc_mem_entry *rproc_mem;
+ struct zynqmp_r5_core *r5_core;
+ struct reserved_mem *rmem;
+ int i, num_mem_regions;
+
+ r5_core = (struct zynqmp_r5_core *)rproc->priv;
+ num_mem_regions = r5_core->rmem_count;
+
+ for (i = 0; i < num_mem_regions; i++) {
+ rmem = r5_core->rmem[i];
+
+ if (!strncmp(rmem->name, "vdev0buffer", strlen("vdev0buffer"))) {
+ /* Init reserved memory for vdev buffer */
+ rproc_mem = rproc_of_resm_mem_entry_init(&rproc->dev, i,
+ rmem->size,
+ rmem->base,
+ rmem->name);
+ } else {
+ /* Register associated reserved memory regions */
+ rproc_mem = rproc_mem_entry_init(&rproc->dev, NULL,
+ (dma_addr_t)rmem->base,
+ rmem->size, rmem->base,
+ zynqmp_r5_mem_region_map,
+ zynqmp_r5_mem_region_unmap,
+ rmem->name);
+ }
+
+ if (!rproc_mem)
+ return -ENOMEM;
+
+ rproc_add_carveout(rproc, rproc_mem);
+
+ dev_dbg(&rproc->dev, "reserved mem carveout %s addr=%llx, size=0x%llx",
+ rmem->name, rmem->base, rmem->size);
+ }
+
+ return 0;
+}
+
+/*
+ * tcm_mem_unmap()
+ * @rproc: single R5 core's corresponding rproc instance
+ * @mem: tcm mem entry to unmap
+ *
+ * Unmap TCM banks when powering down R5 core.
+ *
+ * return always 0
+ */
+static int tcm_mem_unmap(struct rproc *rproc, struct rproc_mem_entry *mem)
+{
+ iounmap((void __iomem *)mem->va);
+
+ return 0;
+}
+
+/*
+ * tcm_mem_map()
+ * @rproc: single R5 core's corresponding rproc instance
+ * @mem: tcm memory entry descriptor
+ *
+ * Given TCM bank entry, this func setup virtual address for TCM bank
+ * remoteproc carveout. It also takes care of va to da address translation
+ *
+ * return 0 on success, otherwise non-zero value on failure
+ */
+static int tcm_mem_map(struct rproc *rproc,
+ struct rproc_mem_entry *mem)
+{
+ void __iomem *va;
+
+ va = ioremap_wc(mem->dma, mem->len);
+ if (IS_ERR_OR_NULL(va))
+ return -ENOMEM;
+
+ /* Update memory entry va */
+ mem->va = (void *)va;
+
+ /* clear TCMs */
+ memset_io(va, 0, mem->len);
+
+ /*
+ * The R5s expect their TCM banks to be at address 0x0 and 0x2000,
+ * while on the Linux side they are at 0xffexxxxx.
+ *
+ * Zero out the high 12 bits of the address. This will give
+ * expected values for TCM Banks 0A and 0B (0x0 and 0x20000).
+ */
+ mem->da &= 0x000fffff;
+
+ /*
+ * TCM Banks 1A and 1B still have to be translated.
+ *
+ * Below handle these two banks' absolute addresses (0xffe90000 and
+ * 0xffeb0000) and convert to the expected relative addresses
+ * (0x0 and 0x20000).
+ */
+ if (mem->da == 0x90000 || mem->da == 0xB0000)
+ mem->da -= 0x90000;
+
+ /* if translated TCM bank address is not valid report error */
+ if (mem->da != 0x0 && mem->da != 0x20000) {
+ dev_err(&rproc->dev, "invalid TCM address: %x\n", mem->da);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * add_tcm_carveout_split_mode()
+ * @rproc: single R5 core's corresponding rproc instance
+ *
+ * allocate and add remoteproc carveout for TCM memory in split mode
+ *
+ * return 0 on success, otherwise non-zero value on failure
+ */
+static int add_tcm_carveout_split_mode(struct rproc *rproc)
+{
+ struct rproc_mem_entry *rproc_mem;
+ struct zynqmp_r5_core *r5_core;
+ int i, num_banks, ret;
+ phys_addr_t bank_addr;
+ struct device *dev;
+ u32 pm_domain_id;
+ size_t bank_size;
+ char *bank_name;
+
+ r5_core = (struct zynqmp_r5_core *)rproc->priv;
+ dev = r5_core->dev;
+ num_banks = r5_core->tcm_bank_count;
+
+ /*
+ * Power-on Each 64KB TCM,
+ * register its address space, map and unmap functions
+ * and add carveouts accordingly
+ */
+ for (i = 0; i < num_banks; i++) {
+ bank_addr = r5_core->tcm_banks[i]->addr;
+ bank_name = r5_core->tcm_banks[i]->bank_name;
+ bank_size = r5_core->tcm_banks[i]->size;
+ pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
+
+ ret = zynqmp_pm_request_node(pm_domain_id,
+ ZYNQMP_PM_CAPABILITY_ACCESS, 0,
+ ZYNQMP_PM_REQUEST_ACK_BLOCKING);
+ if (ret < 0) {
+ dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
+ goto release_tcm_split;
+ }
+
+ dev_dbg(dev, "TCM carveout split mode %s addr=%llx, size=0x%lx",
+ bank_name, bank_addr, bank_size);
+
+ rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
+ bank_size, bank_addr,
+ tcm_mem_map, tcm_mem_unmap,
+ bank_name);
+ if (!rproc_mem) {
+ ret = -ENOMEM;
+ zynqmp_pm_release_node(pm_domain_id);
+ goto release_tcm_split;
+ }
+
+ rproc_add_carveout(rproc, rproc_mem);
+ }
+
+ return 0;
+
+release_tcm_split:
+ /* If failed, Turn off all TCM banks turned on before */
+ for (i--; i >= 0; i--) {
+ pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
+ zynqmp_pm_release_node(pm_domain_id);
+ }
+ return ret;
+}
+
+/*
+ * add_tcm_carveout_lockstep_mode()
+ * @rproc: single R5 core's corresponding rproc instance
+ *
+ * allocate and add remoteproc carveout for TCM memory in lockstep mode
+ *
+ * return 0 on success, otherwise non-zero value on failure
+ */
+static int add_tcm_carveout_lockstep_mode(struct rproc *rproc)
+{
+ struct rproc_mem_entry *rproc_mem;
+ struct zynqmp_r5_core *r5_core;
+ int i, num_banks, ret;
+ phys_addr_t bank_addr;
+ size_t bank_size = 0;
+ struct device *dev;
+ u32 pm_domain_id;
+ char *bank_name;
+
+ r5_core = (struct zynqmp_r5_core *)rproc->priv;
+ dev = r5_core->dev;
+
+ /* Go through zynqmp banks for r5 node */
+ num_banks = r5_core->tcm_bank_count;
+
+ /*
+ * In lockstep mode, TCM is contiguous memory block
+ * However, each TCM block still needs to be enabled individually.
+ * So, Enable each TCM block individually, but add their size
+ * to create contiguous memory region.
+ */
+ bank_addr = r5_core->tcm_banks[0]->addr;
+ bank_name = r5_core->tcm_banks[0]->bank_name;
+
+ for (i = 0; i < num_banks; i++) {
+ bank_size += r5_core->tcm_banks[i]->size;
+ pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
+
+ /* Turn on each TCM bank individually */
+ ret = zynqmp_pm_request_node(pm_domain_id,
+ ZYNQMP_PM_CAPABILITY_ACCESS, 0,
+ ZYNQMP_PM_REQUEST_ACK_BLOCKING);
+ if (ret < 0) {
+ dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
+ goto release_tcm_lockstep;
+ }
+ }
+
+ dev_dbg(dev, "TCM add carveout lockstep mode %s addr=0x%llx, size=0x%lx",
+ bank_name, bank_addr, bank_size);
+
+ /* Register TCM address range, TCM map and unmap functions */
+ rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
+ bank_size, bank_addr,
+ tcm_mem_map, tcm_mem_unmap,
+ bank_name);
+ if (!rproc_mem) {
+ ret = -ENOMEM;
+ goto release_tcm_lockstep;
+ }
+
+ /* If registration is success, add carveouts */
+ rproc_add_carveout(rproc, rproc_mem);
+
+ return 0;
+
+release_tcm_lockstep:
+ /* If failed, Turn off all TCM banks turned on before */
+ for (i--; i >= 0; i--) {
+ pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
+ zynqmp_pm_release_node(pm_domain_id);
+ }
+ return ret;
+}
+
+/*
+ * add_tcm_banks()
+ * @rproc: single R5 core's corresponding rproc instance
+ *
+ * allocate and add remoteproc carveouts for TCM memory based on cluster mode
+ *
+ * return 0 on success, otherwise non-zero value on failure
+ */
+static int add_tcm_banks(struct rproc *rproc)
+{
+ struct zynqmp_r5_cluster *cluster;
+ struct zynqmp_r5_core *r5_core;
+ struct device *dev;
+
+ r5_core = (struct zynqmp_r5_core *)rproc->priv;
+ if (!r5_core)
+ return -EINVAL;
+
+ dev = r5_core->dev;
+
+ cluster = dev_get_drvdata(dev->parent);
+ if (!cluster) {
+ dev_err(dev->parent, "Invalid driver data\n");
+ return -EINVAL;
+ }
+
+ /*
+ * In lockstep mode TCM banks are one contiguous memory region of 256Kb
+ * In split mode, each TCM bank is 64Kb and not contiguous.
+ * We add memory carveouts accordingly.
+ */
+ if (cluster->mode == SPLIT_MODE)
+ return add_tcm_carveout_split_mode(rproc);
+ else if (cluster->mode == LOCKSTEP_MODE)
+ return add_tcm_carveout_lockstep_mode(rproc);
+
+ return -EINVAL;
+}
+
+/*
+ * zynqmp_r5_parse_fw()
+ * @rproc: single R5 core's corresponding rproc instance
+ * @fw: ptr to firmware to be loaded onto r5 core
+ *
+ * get resource table if available
+ *
+ * return 0 on success, otherwise non-zero value on failure
+ */
+static int zynqmp_r5_parse_fw(struct rproc *rproc, const struct firmware *fw)
+{
+ int ret;
+
+ ret = rproc_elf_load_rsc_table(rproc, fw);
+ if (ret == -EINVAL) {
+ /*
+ * resource table only required for IPC.
+ * if not present, this is not necessarily an error;
+ * for example, loading r5 hello world application
+ * so simply inform user and keep going.
+ */
+ dev_info(&rproc->dev, "no resource table found.\n");
+ ret = 0;
+ }
+ return ret;
+}
+
+/**
+ * zynqmp_r5_rproc_prepare()
+ * adds carveouts for TCM bank and reserved memory regions
+ *
+ * @rproc: Device node of each rproc
+ *
+ * Return: 0 for success else < 0 error code
+ */
+static int zynqmp_r5_rproc_prepare(struct rproc *rproc)
+{
+ int ret;
+
+ ret = add_tcm_banks(rproc);
+ if (ret) {
+ dev_err(&rproc->dev, "failed to get TCM banks, err %d\n", ret);
+ return ret;
+ }
+
+ ret = add_mem_regions_carveout(rproc);
+ if (ret) {
+ dev_err(&rproc->dev, "failed to get reserve mem regions %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * zynqmp_r5_rproc_unprepare()
+ * Turns off TCM banks using power-domain id
+ *
+ * @rproc: Device node of each rproc
+ *
+ * Return: always 0
+ */
+static int zynqmp_r5_rproc_unprepare(struct rproc *rproc)
+{
+ struct zynqmp_r5_core *r5_core;
+ u32 pm_domain_id;
+ int i;
+
+ r5_core = (struct zynqmp_r5_core *)rproc->priv;
+
+ for (i = 0; i < r5_core->tcm_bank_count; i++) {
+ pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
+ if (zynqmp_pm_release_node(pm_domain_id))
+ dev_warn(r5_core->dev,
+ "can't turn off TCM bank 0x%x", pm_domain_id);
+ }
+
+ return 0;
+}
+
+static const struct rproc_ops zynqmp_r5_rproc_ops = {
+ .prepare = zynqmp_r5_rproc_prepare,
+ .unprepare = zynqmp_r5_rproc_unprepare,
+ .start = zynqmp_r5_rproc_start,
+ .stop = zynqmp_r5_rproc_stop,
+ .load = rproc_elf_load_segments,
+ .parse_fw = zynqmp_r5_parse_fw,
+ .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
+ .sanity_check = rproc_elf_sanity_check,
+ .get_boot_addr = rproc_elf_get_boot_addr,
+};
+
+/**
+ * zynqmp_r5_add_rproc_core()
+ * Allocate and add struct rproc object for each r5f core
+ * This is called for each individual r5f core
+ *
+ * @cdev: Device node of each r5 core
+ *
+ * Return: zynqmp_r5_core object for success else error code pointer
+ */
+static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
+{
+ struct zynqmp_r5_core *r5_core;
+ struct rproc *r5_rproc;
+ int ret;
+
+ /* Set up DMA mask */
+ ret = dma_set_coherent_mask(cdev, DMA_BIT_MASK(32));
+ if (ret)
+ return ERR_PTR(ret);
+
+ /* Allocate remoteproc instance */
+ r5_rproc = rproc_alloc(cdev, dev_name(cdev),
+ &zynqmp_r5_rproc_ops,
+ NULL, sizeof(struct zynqmp_r5_core));
+ if (!r5_rproc) {
+ dev_err(cdev, "failed to allocate memory for rproc instance\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ r5_rproc->auto_boot = false;
+ r5_core = (struct zynqmp_r5_core *)r5_rproc->priv;
+ r5_core->dev = cdev;
+ r5_core->np = dev_of_node(cdev);
+ if (!r5_core->np) {
+ dev_err(cdev, "can't get device node for r5 core\n");
+ ret = -EINVAL;
+ goto free_rproc;
+ }
+
+ /* Add R5 remoteproc core */
+ ret = rproc_add(r5_rproc);
+ if (ret) {
+ dev_err(cdev, "failed to add r5 remoteproc\n");
+ goto free_rproc;
+ }
+
+ r5_core->rproc = r5_rproc;
+ return r5_core;
+
+free_rproc:
+ rproc_free(r5_rproc);
+ return ERR_PTR(ret);
+}
+
+/**
+ * zynqmp_r5_get_tcm_node()
+ * Ideally this function should parse tcm node and store information
+ * in r5_core instance. For now, Hardcoded TCM information is used.
+ * This approach is used as TCM bindings for system-dt is being developed
+ *
+ * @cluster: pointer to zynqmp_r5_cluster type object
+ *
+ * Return: 0 for success and < 0 error code for failure.
+ */
+static int zynqmp_r5_get_tcm_node(struct zynqmp_r5_cluster *cluster)
+{
+ struct device *dev = cluster->dev;
+ struct zynqmp_r5_core *r5_core;
+ int tcm_bank_count, tcm_node;
+ int i, j;
+
+ tcm_bank_count = ARRAY_SIZE(zynqmp_tcm_banks);
+
+ /* count per core tcm banks */
+ tcm_bank_count = tcm_bank_count / cluster->core_count;
+
+ /*
+ * r5 core 0 will use all of TCM banks in lockstep mode.
+ * In split mode, r5 core0 will use 128k and r5 core1 will use another
+ * 128k. Assign TCM banks to each core accordingly
+ */
+ tcm_node = 0;
+ for (i = 0; i < cluster->core_count; i++) {
+ r5_core = cluster->r5_cores[i];
+ r5_core->tcm_banks = devm_kcalloc(dev, tcm_bank_count,
+ sizeof(struct mem_bank_data *),
+ GFP_KERNEL);
+ if (!r5_core->tcm_banks)
+ return -ENOMEM;
+
+ for (j = 0; j < tcm_bank_count; j++) {
+ /*
+ * Use pre-defined TCM reg values.
+ * Eventually this should be replaced by values
+ * parsed from dts.
+ */
+ r5_core->tcm_banks[j] =
+ (struct mem_bank_data *)&zynqmp_tcm_banks[tcm_node];
+ tcm_node++;
+ }
+
+ r5_core->tcm_bank_count = tcm_bank_count;
+ }
+
+ return 0;
+}
+
+/**
+ * zynqmp_r5_get_mem_region_node()
+ * parse memory-region property and get reserved mem regions
+ *
+ * @r5_core: pointer to zynqmp_r5_core type object
+ *
+ * Return: 0 for success and error code for failure.
+ */
+static int zynqmp_r5_get_mem_region_node(struct zynqmp_r5_core *r5_core)
+{
+ struct device_node *np, *rmem_np;
+ struct reserved_mem **rmem;
+ int res_mem_count, i;
+ struct device *dev;
+
+ dev = r5_core->dev;
+ np = r5_core->np;
+
+ res_mem_count = of_property_count_elems_of_size(np, "memory-region",
+ sizeof(phandle));
+ if (res_mem_count <= 0) {
+ dev_warn(dev, "failed to get memory-region property %d\n",
+ res_mem_count);
+ return 0;
+ }
+
+ rmem = devm_kcalloc(dev, res_mem_count,
+ sizeof(struct reserved_mem *), GFP_KERNEL);
+ if (!rmem)
+ return -ENOMEM;
+
+ for (i = 0; i < res_mem_count; i++) {
+ rmem_np = of_parse_phandle(np, "memory-region", i);
+ if (!rmem_np)
+ goto release_rmem;
+
+ rmem[i] = of_reserved_mem_lookup(rmem_np);
+ if (!rmem[i]) {
+ of_node_put(rmem_np);
+ goto release_rmem;
+ }
+
+ of_node_put(rmem_np);
+ }
+
+ r5_core->rmem_count = res_mem_count;
+ r5_core->rmem = rmem;
+ return 0;
+
+release_rmem:
+ return -EINVAL;
+}
+
+/*
+ * zynqmp_r5_core_init()
+ * Create and initialize zynqmp_r5_core type object
+ *
+ * @cluster: pointer to zynqmp_r5_cluster type object
+ * @fw_reg_val: value expected by firmware to configure RPU cluster mode
+ * @tcm_mode: value expected by fw to configure TCM mode (lockstep or split)
+ *
+ * Return: 0 for success and error code for failure.
+ */
+static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
+ enum rpu_oper_mode fw_reg_val,
+ enum rpu_tcm_comb tcm_mode)
+{
+ struct device *dev = cluster->dev;
+ struct zynqmp_r5_core *r5_core;
+ int ret, i;
+
+ ret = zynqmp_r5_get_tcm_node(cluster);
+ if (ret < 0) {
+ dev_err(dev, "can't get tcm node, err %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < cluster->core_count; i++) {
+ r5_core = cluster->r5_cores[i];
+
+ ret = zynqmp_r5_get_mem_region_node(r5_core);
+ if (ret)
+ dev_warn(dev, "memory-region prop failed %d\n", ret);
+
+ /* Initialize r5 cores with power-domains parsed from dts */
+ ret = of_property_read_u32_index(r5_core->np, "power-domains",
+ 1, &r5_core->pm_domain_id);
+ if (ret) {
+ dev_err(dev, "failed to get power-domains property\n");
+ return ret;
+ }
+
+ ret = zynqmp_r5_set_mode(r5_core, fw_reg_val, tcm_mode);
+ if (ret) {
+ dev_err(dev, "failed to set r5 cluster mode %d, err %d\n",
+ cluster->mode, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * zynqmp_r5_cluster_init()
+ * Create and initialize zynqmp_r5_cluster type object
+ *
+ * @cluster: pointer to zynqmp_r5_cluster type object
+ *
+ * Return: 0 for success and error code for failure.
+ */
+static int zynqmp_r5_cluster_init(struct zynqmp_r5_cluster *cluster)
+{
+ enum zynqmp_r5_cluster_mode cluster_mode = LOCKSTEP_MODE;
+ struct device *dev = cluster->dev;
+ struct device_node *dev_node = dev_of_node(dev);
+ struct platform_device *child_pdev;
+ struct zynqmp_r5_core **r5_cores;
+ enum rpu_oper_mode fw_reg_val;
+ struct device **child_devs;
+ struct device_node *child;
+ enum rpu_tcm_comb tcm_mode;
+ int core_count, ret, i;
+
+ ret = of_property_read_u32(dev_node, "xlnx,cluster-mode", &cluster_mode);
+
+ /*
+ * on success returns 0, if not defined then returns -EINVAL,
+ * In that case, default is LOCKSTEP mode. Other than that
+ * returns relative error code < 0.
+ */
+ if (ret != -EINVAL && ret != 0) {
+ dev_err(dev, "Invalid xlnx,cluster-mode property\n");
+ return ret;
+ }
+
+ /*
+ * For now driver only supports split mode and lockstep mode.
+ * fail driver probe if either of that is not set in dts.
+ */
+ if (cluster_mode == LOCKSTEP_MODE) {
+ tcm_mode = PM_RPU_TCM_COMB;
+ fw_reg_val = PM_RPU_MODE_LOCKSTEP;
+ } else if (cluster_mode == SPLIT_MODE) {
+ tcm_mode = PM_RPU_TCM_SPLIT;
+ fw_reg_val = PM_RPU_MODE_SPLIT;
+ } else {
+ dev_err(dev, "driver does not support cluster mode %d\n", cluster_mode);
+ return -EINVAL;
+ }
+
+ /*
+ * Number of cores is decided by number of child nodes of
+ * r5f subsystem node in dts. If Split mode is used in dts
+ * 2 child nodes are expected.
+ * In lockstep mode if two child nodes are available,
+ * only use first child node and consider it as core0
+ * and ignore core1 dt node.
+ */
+ core_count = of_get_available_child_count(dev_node);
+ if (core_count == 0) {
+ dev_err(dev, "Invalid number of r5 cores %d", core_count);
+ return -EINVAL;
+ } else if (cluster_mode == SPLIT_MODE && core_count != 2) {
+ dev_err(dev, "Invalid number of r5 cores for split mode\n");
+ return -EINVAL;
+ } else if (cluster_mode == LOCKSTEP_MODE && core_count == 2) {
+ dev_warn(dev, "Only r5 core0 will be used\n");
+ core_count = 1;
+ }
+
+ child_devs = kcalloc(core_count, sizeof(struct device *), GFP_KERNEL);
+ if (!child_devs)
+ return -ENOMEM;
+
+ r5_cores = kcalloc(core_count,
+ sizeof(struct zynqmp_r5_core *), GFP_KERNEL);
+ if (!r5_cores) {
+ kfree(child_devs);
+ return -ENOMEM;
+ }
+
+ i = 0;
+ for_each_available_child_of_node(dev_node, child) {
+ child_pdev = of_find_device_by_node(child);
+ if (!child_pdev) {
+ of_node_put(child);
+ ret = -ENODEV;
+ goto release_r5_cores;
+ }
+
+ child_devs[i] = &child_pdev->dev;
+
+ /* create and add remoteproc instance of type struct rproc */
+ r5_cores[i] = zynqmp_r5_add_rproc_core(&child_pdev->dev);
+ if (IS_ERR(r5_cores[i])) {
+ of_node_put(child);
+ ret = PTR_ERR(r5_cores[i]);
+ r5_cores[i] = NULL;
+ goto release_r5_cores;
+ }
+
+ /*
+ * If two child nodes are available in dts in lockstep mode,
+ * then ignore second child node.
+ */
+ if (cluster_mode == LOCKSTEP_MODE) {
+ of_node_put(child);
+ break;
+ }
+
+ i++;
+ }
+
+ cluster->mode = cluster_mode;
+ cluster->core_count = core_count;
+ cluster->r5_cores = r5_cores;
+
+ ret = zynqmp_r5_core_init(cluster, fw_reg_val, tcm_mode);
+ if (ret < 0) {
+ dev_err(dev, "failed to init r5 core err %d\n", ret);
+ cluster->core_count = 0;
+ cluster->r5_cores = NULL;
+
+ /*
+ * at this point rproc resources for each core are allocated.
+ * adjust index to free resources in reverse order
+ */
+ i = core_count - 1;
+ goto release_r5_cores;
+ }
+
+ kfree(child_devs);
+ return 0;
+
+release_r5_cores:
+ while (i >= 0) {
+ put_device(child_devs[i]);
+ if (r5_cores[i]) {
+ of_reserved_mem_device_release(r5_cores[i]->dev);
+ rproc_del(r5_cores[i]->rproc);
+ rproc_free(r5_cores[i]->rproc);
+ }
+ i--;
+ }
+ kfree(r5_cores);
+ kfree(child_devs);
+ return ret;
+}
+
+static void zynqmp_r5_cluster_exit(void *data)
+{
+ struct platform_device *pdev = (struct platform_device *)data;
+ struct zynqmp_r5_cluster *cluster;
+ struct zynqmp_r5_core *r5_core;
+ int i;
+
+ cluster = (struct zynqmp_r5_cluster *)platform_get_drvdata(pdev);
+ if (!cluster)
+ return;
+
+ for (i = 0; i < cluster->core_count; i++) {
+ r5_core = cluster->r5_cores[i];
+ of_reserved_mem_device_release(r5_core->dev);
+ put_device(r5_core->dev);
+ rproc_del(r5_core->rproc);
+ rproc_free(r5_core->rproc);
+ }
+
+ kfree(cluster->r5_cores);
+ kfree(cluster);
+ platform_set_drvdata(pdev, NULL);
+}
+
+/*
+ * zynqmp_r5_remoteproc_probe()
+ * parse device-tree, initialize hardware and allocate required resources
+ * and remoteproc ops
+ *
+ * @pdev: domain platform device for R5 cluster
+ *
+ * Return: 0 for success and < 0 for failure.
+ */
+static int zynqmp_r5_remoteproc_probe(struct platform_device *pdev)
+{
+ struct zynqmp_r5_cluster *cluster;
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ cluster = kzalloc(sizeof(*cluster), GFP_KERNEL);
+ if (!cluster)
+ return -ENOMEM;
+
+ cluster->dev = dev;
+
+ ret = devm_of_platform_populate(dev);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to populate platform dev\n");
+ kfree(cluster);
+ return ret;
+ }
+
+ /* wire in so each core can be cleaned up at driver remove */
+ platform_set_drvdata(pdev, cluster);
+
+ ret = zynqmp_r5_cluster_init(cluster);
+ if (ret) {
+ kfree(cluster);
+ platform_set_drvdata(pdev, NULL);
+ dev_err_probe(dev, ret, "Invalid r5f subsystem device tree\n");
+ return ret;
+ }
+
+ ret = devm_add_action_or_reset(dev, zynqmp_r5_cluster_exit, pdev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/* Match table for OF platform binding */
+static const struct of_device_id zynqmp_r5_remoteproc_match[] = {
+ { .compatible = "xlnx,zynqmp-r5fss", },
+ { /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, zynqmp_r5_remoteproc_match);
+
+static struct platform_driver zynqmp_r5_remoteproc_driver = {
+ .probe = zynqmp_r5_remoteproc_probe,
+ .driver = {
+ .name = "zynqmp_r5_remoteproc",
+ .of_match_table = zynqmp_r5_remoteproc_match,
+ },
+};
+module_platform_driver(zynqmp_r5_remoteproc_driver);
+
+MODULE_DESCRIPTION("Xilinx R5F remote processor driver");
+MODULE_AUTHOR("Xilinx Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 2bb640d1521d..677d2601d305 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -540,12 +540,6 @@ config RTC_DRV_BQ32K
This driver can also be built as a module. If so, the module
will be called rtc-bq32k.
-config RTC_DRV_DM355EVM
- tristate "TI DaVinci DM355 EVM RTC"
- depends on MFD_DM355EVM_MSP
- help
- Supports the RTC firmware in the MSP430 on the DM355 EVM.
-
config RTC_DRV_TWL92330
bool "TI TWL92330/Menelaus"
depends on MENELAUS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 791994eb913d..d3c042dcbc73 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -45,7 +45,6 @@ obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o
obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o
obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o
obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o
-obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o
obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c
deleted file mode 100644
index 94fb16ac3e0f..000000000000
--- a/drivers/rtc/rtc-dm355evm.c
+++ /dev/null
@@ -1,151 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * rtc-dm355evm.c - access battery-backed counter in MSP430 firmware
- *
- * Copyright (c) 2008 by David Brownell
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/rtc.h>
-#include <linux/platform_device.h>
-
-#include <linux/mfd/dm355evm_msp.h>
-#include <linux/module.h>
-
-
-/*
- * The MSP430 firmware on the DM355 EVM uses a watch crystal to feed
- * a 1 Hz counter. When a backup battery is supplied, that makes a
- * reasonable RTC for applications where alarms and non-NTP drift
- * compensation aren't important.
- *
- * The only real glitch is the inability to read or write all four
- * counter bytes atomically: the count may increment in the middle
- * of an operation, causing trouble when the LSB rolls over.
- *
- * This driver was tested with firmware revision A4.
- */
-union evm_time {
- u8 bytes[4];
- u32 value;
-};
-
-static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- union evm_time time;
- int status;
- int tries = 0;
-
- do {
- /*
- * Read LSB(0) to MSB(3) bytes. Defend against the counter
- * rolling over by re-reading until the value is stable,
- * and assuming the four reads take at most a few seconds.
- */
- status = dm355evm_msp_read(DM355EVM_MSP_RTC_0);
- if (status < 0)
- return status;
- if (tries && time.bytes[0] == status)
- break;
- time.bytes[0] = status;
-
- status = dm355evm_msp_read(DM355EVM_MSP_RTC_1);
- if (status < 0)
- return status;
- if (tries && time.bytes[1] == status)
- break;
- time.bytes[1] = status;
-
- status = dm355evm_msp_read(DM355EVM_MSP_RTC_2);
- if (status < 0)
- return status;
- if (tries && time.bytes[2] == status)
- break;
- time.bytes[2] = status;
-
- status = dm355evm_msp_read(DM355EVM_MSP_RTC_3);
- if (status < 0)
- return status;
- if (tries && time.bytes[3] == status)
- break;
- time.bytes[3] = status;
-
- } while (++tries < 5);
-
- dev_dbg(dev, "read timestamp %08x\n", time.value);
-
- rtc_time64_to_tm(le32_to_cpu(time.value), tm);
- return 0;
-}
-
-static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- union evm_time time;
- unsigned long value;
- int status;
-
- value = rtc_tm_to_time64(tm);
- time.value = cpu_to_le32(value);
-
- dev_dbg(dev, "write timestamp %08x\n", time.value);
-
- /*
- * REVISIT handle non-atomic writes ... maybe just retry until
- * byte[1] sticks (no rollover)?
- */
- status = dm355evm_msp_write(time.bytes[0], DM355EVM_MSP_RTC_0);
- if (status < 0)
- return status;
-
- status = dm355evm_msp_write(time.bytes[1], DM355EVM_MSP_RTC_1);
- if (status < 0)
- return status;
-
- status = dm355evm_msp_write(time.bytes[2], DM355EVM_MSP_RTC_2);
- if (status < 0)
- return status;
-
- status = dm355evm_msp_write(time.bytes[3], DM355EVM_MSP_RTC_3);
- if (status < 0)
- return status;
-
- return 0;
-}
-
-static const struct rtc_class_ops dm355evm_rtc_ops = {
- .read_time = dm355evm_rtc_read_time,
- .set_time = dm355evm_rtc_set_time,
-};
-
-/*----------------------------------------------------------------------*/
-
-static int dm355evm_rtc_probe(struct platform_device *pdev)
-{
- struct rtc_device *rtc;
-
- rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(rtc))
- return PTR_ERR(rtc);
-
- platform_set_drvdata(pdev, rtc);
-
- rtc->ops = &dm355evm_rtc_ops;
- rtc->range_max = U32_MAX;
-
- return devm_rtc_register_device(rtc);
-}
-
-/*
- * I2C is used to talk to the MSP430, but this platform device is
- * exposed by an MFD driver that manages I2C communications.
- */
-static struct platform_driver rtc_dm355evm_driver = {
- .probe = dm355evm_rtc_probe,
- .driver = {
- .name = "rtc-dm355evm",
- },
-};
-
-module_platform_driver(rtc_dm355evm_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 5fb1f364e815..1d1cf641937c 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -738,6 +738,7 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,
sk->sk_reuse = SK_CAN_REUSE;
sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
sk->sk_allocation = GFP_ATOMIC;
+ sk->sk_use_task_frag = false;
sk_set_memalloc(sk);
sock_no_linger(sk);
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
index 4b592820845a..1595a9607775 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
@@ -108,8 +108,8 @@ sun6i_isp_capture_buffer_configure(struct sun6i_isp_device *isp_dev,
void sun6i_isp_capture_configure(struct sun6i_isp_device *isp_dev)
{
unsigned int width, height;
- unsigned int stride_luma, stride_chroma = 0;
- unsigned int stride_luma_div4, stride_chroma_div4;
+ unsigned int stride_luma, stride_chroma;
+ unsigned int stride_luma_div4, stride_chroma_div4 = 0;
const struct sun6i_isp_capture_format *format;
const struct v4l2_format_info *info;
u32 pixelformat;
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
index 8039e311cb1c..e28be895b486 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
@@ -183,8 +183,8 @@ void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev)
if (state->configured)
goto complete;
- sun6i_isp_params_configure_modules(isp_dev,
- &sun6i_isp_params_config_default);
+ sun6i_isp_params_configure_modules(isp_dev,
+ &sun6i_isp_params_config_default);
state->configured = true;
@@ -208,6 +208,8 @@ static void sun6i_isp_params_state_cleanup(struct sun6i_isp_device *isp_dev,
vb2_buffer = &state->pending->v4l2_buffer.vb2_buf;
vb2_buffer_done(vb2_buffer, error ? VB2_BUF_STATE_ERROR :
VB2_BUF_STATE_QUEUED);
+
+ state->pending = NULL;
}
list_for_each_entry(isp_buffer, &state->queue, list) {
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c
index d69d2be0add2..1ca4673df2b3 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c
@@ -173,8 +173,7 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
struct sun6i_isp_proc_source *source;
struct v4l2_subdev *source_subdev;
struct media_pad *remote_pad;
- /* Initialize to 0 to use both in disable label (ret != 0) and off. */
- int ret = 0;
+ int ret;
/* Source */
@@ -195,6 +194,7 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
if (!on) {
sun6i_isp_proc_irq_disable(isp_dev);
v4l2_subdev_call(source_subdev, video, s_stream, 0);
+ ret = 0;
goto disable;
}
@@ -342,7 +342,7 @@ static const struct v4l2_subdev_pad_ops sun6i_isp_proc_pad_ops = {
.set_fmt = sun6i_isp_proc_set_fmt,
};
-const struct v4l2_subdev_ops sun6i_isp_proc_subdev_ops = {
+static const struct v4l2_subdev_ops sun6i_isp_proc_subdev_ops = {
.video = &sun6i_isp_proc_video_ops,
.pad = &sun6i_isp_proc_pad_ops,
};
@@ -416,7 +416,7 @@ static int sun6i_isp_proc_notifier_bound(struct v4l2_async_notifier *notifier,
enabled = !proc->source_csi0.expected;
break;
default:
- break;
+ return -EINVAL;
}
source->subdev = remote_subdev;
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c
index f8b326eed54d..a2b2da1255dd 100644
--- a/drivers/usb/usbip/usbip_common.c
+++ b/drivers/usb/usbip/usbip_common.c
@@ -315,6 +315,7 @@ int usbip_recv(struct socket *sock, void *buf, int size)
do {
sock->sk->sk_allocation = GFP_NOIO;
+ sock->sk->sk_use_task_frag = false;
result = sock_recvmsg(sock, &msg, MSG_WAITALL);
if (result <= 0)
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index b0fe02273e87..a479aab90f78 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -648,9 +648,9 @@ static const struct attribute_group adp8860_bl_attr_group = {
.attrs = adp8860_bl_attributes,
};
-static int adp8860_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int adp8860_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct backlight_device *bl;
struct adp8860_bl *data;
struct adp8860_backlight_platform_data *pdata =
@@ -803,7 +803,7 @@ static struct i2c_driver adp8860_driver = {
.name = KBUILD_MODNAME,
.pm = &adp8860_i2c_pm_ops,
},
- .probe = adp8860_probe,
+ .probe_new = adp8860_probe,
.remove = adp8860_remove,
.id_table = adp8860_id,
};
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 5becace3fd0f..d6b0007db649 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -836,9 +836,9 @@ static const struct attribute_group adp8870_bl_attr_group = {
.attrs = adp8870_bl_attributes,
};
-static int adp8870_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int adp8870_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct backlight_properties props;
struct backlight_device *bl;
struct adp8870_bl *data;
@@ -973,7 +973,7 @@ static struct i2c_driver adp8870_driver = {
.name = KBUILD_MODNAME,
.pm = &adp8870_i2c_pm_ops,
},
- .probe = adp8870_probe,
+ .probe_new = adp8870_probe,
.remove = adp8870_remove,
.id_table = adp8870_id,
};
diff --git a/drivers/video/backlight/arcxcnn_bl.c b/drivers/video/backlight/arcxcnn_bl.c
index 060c0eef6a52..555b036643fb 100644
--- a/drivers/video/backlight/arcxcnn_bl.c
+++ b/drivers/video/backlight/arcxcnn_bl.c
@@ -241,7 +241,7 @@ static void arcxcnn_parse_dt(struct arcxcnn *lp)
}
}
-static int arcxcnn_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+static int arcxcnn_probe(struct i2c_client *cl)
{
struct arcxcnn *lp;
int ret;
@@ -395,7 +395,7 @@ static struct i2c_driver arcxcnn_driver = {
.name = "arcxcnn_bl",
.of_match_table = of_match_ptr(arcxcnn_dt_ids),
},
- .probe = arcxcnn_probe,
+ .probe_new = arcxcnn_probe,
.remove = arcxcnn_remove,
.id_table = arcxcnn_ids,
};
diff --git a/drivers/video/backlight/bd6107.c b/drivers/video/backlight/bd6107.c
index a506872d4396..f4db6c064635 100644
--- a/drivers/video/backlight/bd6107.c
+++ b/drivers/video/backlight/bd6107.c
@@ -113,8 +113,7 @@ static const struct backlight_ops bd6107_backlight_ops = {
.check_fb = bd6107_backlight_check_fb,
};
-static int bd6107_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int bd6107_probe(struct i2c_client *client)
{
struct bd6107_platform_data *pdata = dev_get_platdata(&client->dev);
struct backlight_device *backlight;
@@ -193,7 +192,7 @@ static struct i2c_driver bd6107_driver = {
.driver = {
.name = "bd6107",
},
- .probe = bd6107_probe,
+ .probe_new = bd6107_probe,
.remove = bd6107_remove,
.id_table = bd6107_ids,
};
diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
index 475f35635bf6..d8c42acecb5d 100644
--- a/drivers/video/backlight/lm3630a_bl.c
+++ b/drivers/video/backlight/lm3630a_bl.c
@@ -491,8 +491,7 @@ static int lm3630a_parse_node(struct lm3630a_chip *pchip,
return ret;
}
-static int lm3630a_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int lm3630a_probe(struct i2c_client *client)
{
struct lm3630a_platform_data *pdata = dev_get_platdata(&client->dev);
struct lm3630a_chip *pchip;
@@ -617,7 +616,7 @@ static struct i2c_driver lm3630a_i2c_driver = {
.name = LM3630A_NAME,
.of_match_table = lm3630a_match_table,
},
- .probe = lm3630a_probe,
+ .probe_new = lm3630a_probe,
.remove = lm3630a_remove,
.id_table = lm3630a_id,
};
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c
index 6580911671a3..a836628ce06e 100644
--- a/drivers/video/backlight/lm3639_bl.c
+++ b/drivers/video/backlight/lm3639_bl.c
@@ -296,8 +296,7 @@ static const struct regmap_config lm3639_regmap = {
.max_register = REG_MAX,
};
-static int lm3639_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int lm3639_probe(struct i2c_client *client)
{
int ret;
struct lm3639_chip_data *pchip;
@@ -412,7 +411,7 @@ static struct i2c_driver lm3639_i2c_driver = {
.driver = {
.name = LM3639_NAME,
},
- .probe = lm3639_probe,
+ .probe_new = lm3639_probe,
.remove = lm3639_remove,
.id_table = lm3639_id,
};
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
index bd0bdeae23a4..81012bf29baf 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -394,8 +394,9 @@ static int lp855x_parse_acpi(struct lp855x *lp)
return 0;
}
-static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+static int lp855x_probe(struct i2c_client *cl)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(cl);
const struct acpi_device_id *acpi_id = NULL;
struct device *dev = &cl->dev;
struct lp855x *lp;
@@ -586,7 +587,7 @@ static struct i2c_driver lp855x_driver = {
.of_match_table = of_match_ptr(lp855x_dt_ids),
.acpi_match_table = ACPI_PTR(lp855x_acpi_match),
},
- .probe = lp855x_probe,
+ .probe_new = lp855x_probe,
.remove = lp855x_remove,
.id_table = lp855x_ids,
};
diff --git a/drivers/video/backlight/lv5207lp.c b/drivers/video/backlight/lv5207lp.c
index 767b800d79fa..00673c8b66ac 100644
--- a/drivers/video/backlight/lv5207lp.c
+++ b/drivers/video/backlight/lv5207lp.c
@@ -76,8 +76,7 @@ static const struct backlight_ops lv5207lp_backlight_ops = {
.check_fb = lv5207lp_backlight_check_fb,
};
-static int lv5207lp_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int lv5207lp_probe(struct i2c_client *client)
{
struct lv5207lp_platform_data *pdata = dev_get_platdata(&client->dev);
struct backlight_device *backlight;
@@ -142,7 +141,7 @@ static struct i2c_driver lv5207lp_driver = {
.driver = {
.name = "lv5207lp",
},
- .probe = lv5207lp_probe,
+ .probe_new = lv5207lp_probe,
.remove = lv5207lp_remove,
.id_table = lv5207lp_ids,
};
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index f55b3d616a87..77b71f6c19b5 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -75,8 +75,7 @@ static const struct backlight_ops bl_ops = {
.update_status = tosa_bl_update_status,
};
-static int tosa_bl_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tosa_bl_probe(struct i2c_client *client)
{
struct backlight_properties props;
struct tosa_bl_data *data;
@@ -160,7 +159,7 @@ static struct i2c_driver tosa_bl_driver = {
.name = "tosa-bl",
.pm = &tosa_bl_pm_ops,
},
- .probe = tosa_bl_probe,
+ .probe_new = tosa_bl_probe,
.remove = tosa_bl_remove,
.id_table = tosa_bl_id,
};