diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 21:31:17 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 21:31:17 +0300 |
commit | f6cff79f1d122f78a4b35bf4b2f0112afcd89ea4 (patch) | |
tree | cf3a38576f9adbb3860982c25f72aebed2bb541a /drivers/misc | |
parent | 47fcc0360cfb3fe82e4daddacad3c1cd80b0b75d (diff) | |
parent | 9ff6576e124b1227c27c1da43fe5f8ee908263e0 (diff) | |
download | linux-f6cff79f1d122f78a4b35bf4b2f0112afcd89ea4.tar.xz |
Merge tag 'char-misc-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here is the big pull request for char/misc drivers for 4.16-rc1.
There's a lot of stuff in here. Three new driver subsystems were added
for various types of hardware busses:
- siox
- slimbus
- soundwire
as well as a new vboxguest subsystem for the VirtualBox hypervisor
drivers.
There's also big updates from the FPGA subsystem, lots of Android
binder fixes, the usual handful of hyper-v updates, and lots of other
smaller driver updates.
All of these have been in linux-next for a long time, with no reported
issues"
* tag 'char-misc-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (155 commits)
char: lp: use true or false for boolean values
android: binder: use VM_ALLOC to get vm area
android: binder: Use true and false for boolean values
lkdtm: fix handle_irq_event symbol for INT_HW_IRQ_EN
EISA: Delete error message for a failed memory allocation in eisa_probe()
EISA: Whitespace cleanup
misc: remove AVR32 dependencies
virt: vbox: Add error mapping for VERR_INVALID_NAME and VERR_NO_MORE_FILES
soundwire: Fix a signedness bug
uio_hv_generic: fix new type mismatch warnings
uio_hv_generic: fix type mismatch warnings
auxdisplay: img-ascii-lcd: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
uio_hv_generic: add rescind support
uio_hv_generic: check that host supports monitor page
uio_hv_generic: create send and receive buffers
uio: document uio_hv_generic regions
doc: fix documentation about uio_hv_generic
vmbus: add monitor_id and subchannel_id to sysfs per channel
vmbus: fix ABI documentation
uio_hv_generic: use ISR callback method
...
Diffstat (limited to 'drivers/misc')
27 files changed, 160 insertions, 136 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 7c0fa24f9067..6722073e339b 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -53,7 +53,7 @@ config AD525X_DPOT_SPI config ATMEL_TCLIB bool "Atmel AT32/AT91 Timer/Counter Library" - depends on (AVR32 || ARCH_AT91) + depends on ARCH_AT91 help Select this if you want a library to allocate the Timer/Counter blocks found on many Atmel processors. This facilitates using @@ -192,7 +192,7 @@ config ICS932S401 config ATMEL_SSC tristate "Device driver for Atmel SSC peripheral" - depends on HAS_IOMEM && (AVR32 || ARCH_AT91 || COMPILE_TEST) + depends on HAS_IOMEM && (ARCH_AT91 || COMPILE_TEST) ---help--- This option enables device driver support for Atmel Synchronized Serial Communication peripheral (SSC). diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index fe1672747bc1..bc591b7168db 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -3,7 +3,7 @@ * Copyright (c) 2009-2010 Analog Devices, Inc. * Author: Michael Hennerich <hennerich@blackfin.uclinux.org> * - * DEVID #Wipers #Positions Resistor Options (kOhm) + * DEVID #Wipers #Positions Resistor Options (kOhm) * AD5258 1 64 1, 10, 50, 100 * AD5259 1 256 5, 10, 50, 100 * AD5251 2 64 1, 10, 50, 100 @@ -84,12 +84,12 @@ struct dpot_data { struct ad_dpot_bus_data bdata; struct mutex update_lock; - unsigned rdac_mask; - unsigned max_pos; + unsigned int rdac_mask; + unsigned int max_pos; unsigned long devid; - unsigned uid; - unsigned feat; - unsigned wipers; + unsigned int uid; + unsigned int feat; + unsigned int wipers; u16 rdac_cache[MAX_RDACS]; DECLARE_BITMAP(otp_en_mask, MAX_RDACS); }; @@ -126,7 +126,7 @@ static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val) static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg) { - unsigned ctrl = 0; + unsigned int ctrl = 0; int value; if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { @@ -175,7 +175,7 @@ static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg) static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg) { int value; - unsigned ctrl = 0; + unsigned int ctrl = 0; switch (dpot->uid) { case DPOT_UID(AD5246_ID): @@ -238,7 +238,7 @@ static s32 dpot_read(struct dpot_data *dpot, u8 reg) static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value) { - unsigned val = 0; + unsigned int val = 0; if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD | DPOT_ADDR_OTP))) { if (dpot->feat & F_RDACS_WONLY) @@ -328,7 +328,7 @@ static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value) static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value) { /* Only write the instruction byte for certain commands */ - unsigned tmp = 0, ctrl = 0; + unsigned int tmp = 0, ctrl = 0; switch (dpot->uid) { case DPOT_UID(AD5246_ID): @@ -515,11 +515,11 @@ set_##_name(struct device *dev, \ #define DPOT_DEVICE_SHOW_SET(name, reg) \ DPOT_DEVICE_SHOW(name, reg) \ DPOT_DEVICE_SET(name, reg) \ -static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name); +static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name) #define DPOT_DEVICE_SHOW_ONLY(name, reg) \ DPOT_DEVICE_SHOW(name, reg) \ -static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL); +static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL) DPOT_DEVICE_SHOW_SET(rdac0, DPOT_ADDR_RDAC | DPOT_RDAC0); DPOT_DEVICE_SHOW_SET(eeprom0, DPOT_ADDR_EEPROM | DPOT_RDAC0); @@ -616,7 +616,7 @@ set_##_name(struct device *dev, \ { \ return sysfs_do_cmd(dev, attr, buf, count, _cmd); \ } \ -static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name); +static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name) DPOT_DEVICE_DO_CMD(inc_all, DPOT_INC_ALL); DPOT_DEVICE_DO_CMD(dec_all, DPOT_DEC_ALL); @@ -636,7 +636,7 @@ static const struct attribute_group ad525x_group_commands = { }; static int ad_dpot_add_files(struct device *dev, - unsigned features, unsigned rdac) + unsigned int features, unsigned int rdac) { int err = sysfs_create_file(&dev->kobj, dpot_attrib_wipers[rdac]); @@ -661,7 +661,7 @@ static int ad_dpot_add_files(struct device *dev, } static inline void ad_dpot_remove_files(struct device *dev, - unsigned features, unsigned rdac) + unsigned int features, unsigned int rdac) { sysfs_remove_file(&dev->kobj, dpot_attrib_wipers[rdac]); diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h index 6bd1eba23bc0..443a51fd5680 100644 --- a/drivers/misc/ad525x_dpot.h +++ b/drivers/misc/ad525x_dpot.h @@ -195,12 +195,12 @@ enum dpot_devid { struct dpot_data; struct ad_dpot_bus_ops { - int (*read_d8) (void *client); - int (*read_r8d8) (void *client, u8 reg); - int (*read_r8d16) (void *client, u8 reg); - int (*write_d8) (void *client, u8 val); - int (*write_r8d8) (void *client, u8 reg, u8 val); - int (*write_r8d16) (void *client, u8 reg, u16 val); + int (*read_d8)(void *client); + int (*read_r8d8)(void *client, u8 reg); + int (*read_r8d16)(void *client, u8 reg); + int (*write_d8)(void *client, u8 val); + int (*write_r8d8)(void *client, u8 reg, u8 val); + int (*write_r8d16)(void *client, u8 reg, u16 val); }; struct ad_dpot_bus_data { diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index c9f07032c2fc..ed9412d750b7 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -715,6 +715,7 @@ static ssize_t apds990x_rate_avail(struct device *dev, { int i; int pos = 0; + for (i = 0; i < ARRAY_SIZE(arates_hz); i++) pos += sprintf(buf + pos, "%d ", arates_hz[i]); sprintf(buf + pos - 1, "\n"); @@ -725,6 +726,7 @@ static ssize_t apds990x_rate_show(struct device *dev, struct device_attribute *attr, char *buf) { struct apds990x_chip *chip = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", chip->arate); } @@ -784,6 +786,7 @@ static ssize_t apds990x_prox_show(struct device *dev, { ssize_t ret; struct apds990x_chip *chip = dev_get_drvdata(dev); + if (pm_runtime_suspended(dev) || !chip->prox_en) return -EIO; @@ -807,6 +810,7 @@ static ssize_t apds990x_prox_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { struct apds990x_chip *chip = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", chip->prox_en); } @@ -847,6 +851,7 @@ static ssize_t apds990x_prox_reporting_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct apds990x_chip *chip = dev_get_drvdata(dev); + return sprintf(buf, "%s\n", reporting_modes[!!chip->prox_continuous_mode]); } @@ -884,6 +889,7 @@ static ssize_t apds990x_lux_thresh_above_show(struct device *dev, struct device_attribute *attr, char *buf) { struct apds990x_chip *chip = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", chip->lux_thres_hi); } @@ -891,6 +897,7 @@ static ssize_t apds990x_lux_thresh_below_show(struct device *dev, struct device_attribute *attr, char *buf) { struct apds990x_chip *chip = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", chip->lux_thres_lo); } @@ -926,6 +933,7 @@ static ssize_t apds990x_lux_thresh_above_store(struct device *dev, { struct apds990x_chip *chip = dev_get_drvdata(dev); int ret = apds990x_set_lux_thresh(chip, &chip->lux_thres_hi, buf); + if (ret < 0) return ret; return len; @@ -937,6 +945,7 @@ static ssize_t apds990x_lux_thresh_below_store(struct device *dev, { struct apds990x_chip *chip = dev_get_drvdata(dev); int ret = apds990x_set_lux_thresh(chip, &chip->lux_thres_lo, buf); + if (ret < 0) return ret; return len; @@ -954,6 +963,7 @@ static ssize_t apds990x_prox_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { struct apds990x_chip *chip = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", chip->prox_thres); } @@ -1026,6 +1036,7 @@ static ssize_t apds990x_chip_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct apds990x_chip *chip = dev_get_drvdata(dev); + return sprintf(buf, "%s %d\n", chip->chipname, chip->revision); } diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c index 7231260ac287..98a921ea9ee8 100644 --- a/drivers/misc/ds1682.c +++ b/drivers/misc/ds1682.c @@ -59,25 +59,42 @@ static ssize_t ds1682_show(struct device *dev, struct device_attribute *attr, { struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); struct i2c_client *client = to_i2c_client(dev); - __le32 val = 0; + unsigned long long val, check; + __le32 val_le = 0; int rc; dev_dbg(dev, "ds1682_show() called on %s\n", attr->attr.name); /* Read the register */ rc = i2c_smbus_read_i2c_block_data(client, sattr->index, sattr->nr, - (u8 *) & val); + (u8 *)&val_le); if (rc < 0) return -EIO; - /* Special case: the 32 bit regs are time values with 1/4s - * resolution, scale them up to milliseconds */ - if (sattr->nr == 4) - return sprintf(buf, "%llu\n", - ((unsigned long long)le32_to_cpu(val)) * 250); + val = le32_to_cpu(val_le); + + if (sattr->index == DS1682_REG_ELAPSED) { + int retries = 5; + + /* Detect and retry when a tick occurs mid-read */ + do { + rc = i2c_smbus_read_i2c_block_data(client, sattr->index, + sattr->nr, + (u8 *)&val_le); + if (rc < 0 || retries <= 0) + return -EIO; + + check = val; + val = le32_to_cpu(val_le); + retries--; + } while (val != check && val != (check + 1)); + } - /* Format the output string and return # of bytes */ - return sprintf(buf, "%li\n", (long)le32_to_cpu(val)); + /* Format the output string and return # of bytes + * Special case: the 32 bit regs are time values with 1/4s + * resolution, scale them up to milliseconds + */ + return sprintf(buf, "%llu\n", (sattr->nr == 4) ? (val * 250) : val); } static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr, diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 5afe4cd16569..9282ffd607ff 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -276,6 +276,9 @@ static int at25_fw_to_chip(struct device *dev, struct spi_eeprom *chip) return -ENODEV; } switch (val) { + case 9: + chip->flags |= EE_INSTR_BIT3_IS_ADDR; + /* fall through */ case 8: chip->flags |= EE_ADDR1; break; diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index eb29113e0bac..5a17bfeb80d3 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -468,7 +468,7 @@ static struct class enclosure_class = { .dev_groups = enclosure_class_groups, }; -static const char *const enclosure_status [] = { +static const char *const enclosure_status[] = { [ENCLOSURE_STATUS_UNSUPPORTED] = "unsupported", [ENCLOSURE_STATUS_OK] = "OK", [ENCLOSURE_STATUS_CRITICAL] = "critical", @@ -480,7 +480,7 @@ static const char *const enclosure_status [] = { [ENCLOSURE_STATUS_MAX] = NULL, }; -static const char *const enclosure_type [] = { +static const char *const enclosure_type[] = { [ENCLOSURE_COMPONENT_DEVICE] = "device", [ENCLOSURE_COMPONENT_ARRAY_DEVICE] = "array device", }; @@ -680,13 +680,7 @@ ATTRIBUTE_GROUPS(enclosure_component); static int __init enclosure_init(void) { - int err; - - err = class_register(&enclosure_class); - if (err) - return err; - - return 0; + return class_register(&enclosure_class); } static void __exit enclosure_exit(void) diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index 71d2793b372c..607b489a6501 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c @@ -465,6 +465,7 @@ fail1: static int fsa9480_remove(struct i2c_client *client) { struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); + if (client->irq) free_irq(client->irq, usbsw); diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 4fd21e86ad56..c7cd3675bcd1 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -153,11 +153,11 @@ static struct genwqe_dev *genwqe_dev_alloc(void) cd->card_state = GENWQE_CARD_UNUSED; spin_lock_init(&cd->print_lock); - cd->ddcb_software_timeout = genwqe_ddcb_software_timeout; - cd->kill_timeout = genwqe_kill_timeout; + cd->ddcb_software_timeout = GENWQE_DDCB_SOFTWARE_TIMEOUT; + cd->kill_timeout = GENWQE_KILL_TIMEOUT; for (j = 0; j < GENWQE_MAX_VFS; j++) - cd->vf_jobtimeout_msec[j] = genwqe_vf_jobtimeout_msec; + cd->vf_jobtimeout_msec[j] = GENWQE_VF_JOBTIMEOUT_MSEC; genwqe_devices[i] = cd; return cd; @@ -324,11 +324,11 @@ static bool genwqe_setup_pf_jtimer(struct genwqe_dev *cd) u32 T = genwqe_T_psec(cd); u64 x; - if (genwqe_pf_jobtimeout_msec == 0) + if (GENWQE_PF_JOBTIMEOUT_MSEC == 0) return false; /* PF: large value needed, flash update 2sec per block */ - x = ilog2(genwqe_pf_jobtimeout_msec * + x = ilog2(GENWQE_PF_JOBTIMEOUT_MSEC * 16000000000uL/(T * 15)) - 10; genwqe_write_vreg(cd, IO_SLC_VF_APPJOB_TIMEOUT, @@ -904,7 +904,7 @@ static int genwqe_reload_bistream(struct genwqe_dev *cd) * b) a critical GFIR occured * * Informational GFIRs are checked and potentially printed in - * health_check_interval seconds. + * GENWQE_HEALTH_CHECK_INTERVAL seconds. */ static int genwqe_health_thread(void *data) { @@ -918,7 +918,7 @@ static int genwqe_health_thread(void *data) rc = wait_event_interruptible_timeout(cd->health_waitq, (genwqe_health_check_cond(cd, &gfir) || (should_stop = kthread_should_stop())), - genwqe_health_check_interval * HZ); + GENWQE_HEALTH_CHECK_INTERVAL * HZ); if (should_stop) break; @@ -1028,7 +1028,7 @@ static int genwqe_health_check_start(struct genwqe_dev *cd) { int rc; - if (genwqe_health_check_interval <= 0) + if (GENWQE_HEALTH_CHECK_INTERVAL <= 0) return 0; /* valid for disabling the service */ /* moved before request_irq() */ diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index 3743c87f8ab9..1c3967f10f55 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h @@ -47,13 +47,13 @@ #define GENWQE_CARD_NO_MAX (16 * GENWQE_MAX_FUNCS) /* Compile parameters, some of them appear in debugfs for later adjustment */ -#define genwqe_ddcb_max 32 /* DDCBs on the work-queue */ -#define genwqe_polling_enabled 0 /* in case of irqs not working */ -#define genwqe_ddcb_software_timeout 10 /* timeout per DDCB in seconds */ -#define genwqe_kill_timeout 8 /* time until process gets killed */ -#define genwqe_vf_jobtimeout_msec 250 /* 250 msec */ -#define genwqe_pf_jobtimeout_msec 8000 /* 8 sec should be ok */ -#define genwqe_health_check_interval 4 /* <= 0: disabled */ +#define GENWQE_DDCB_MAX 32 /* DDCBs on the work-queue */ +#define GENWQE_POLLING_ENABLED 0 /* in case of irqs not working */ +#define GENWQE_DDCB_SOFTWARE_TIMEOUT 10 /* timeout per DDCB in seconds */ +#define GENWQE_KILL_TIMEOUT 8 /* time until process gets killed */ +#define GENWQE_VF_JOBTIMEOUT_MSEC 250 /* 250 msec */ +#define GENWQE_PF_JOBTIMEOUT_MSEC 8000 /* 8 sec should be ok */ +#define GENWQE_HEALTH_CHECK_INTERVAL 4 /* <= 0: disabled */ /* Sysfs attribute groups used when we create the genwqe device */ extern const struct attribute_group *genwqe_attribute_groups[]; @@ -490,11 +490,9 @@ int genwqe_read_app_id(struct genwqe_dev *cd, char *app_name, int len); /* Memory allocation/deallocation; dma address handling */ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, - void *uaddr, unsigned long size, - struct ddcb_requ *req); + void *uaddr, unsigned long size); -int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m, - struct ddcb_requ *req); +int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m); static inline bool dma_mapping_used(struct dma_mapping *m) { diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index ddfeefe39540..b7f8d35c17a9 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -500,7 +500,7 @@ int __genwqe_wait_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) rc = wait_event_interruptible_timeout(queue->ddcb_waitqs[ddcb_no], ddcb_requ_finished(cd, req), - genwqe_ddcb_software_timeout * HZ); + GENWQE_DDCB_SOFTWARE_TIMEOUT * HZ); /* * We need to distinguish 3 cases here: @@ -633,7 +633,7 @@ int __genwqe_purge_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) __be32 old, new; /* unsigned long flags; */ - if (genwqe_ddcb_software_timeout <= 0) { + if (GENWQE_DDCB_SOFTWARE_TIMEOUT <= 0) { dev_err(&pci_dev->dev, "[%s] err: software timeout is not set!\n", __func__); return -EFAULT; @@ -641,7 +641,7 @@ int __genwqe_purge_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) pddcb = &queue->ddcb_vaddr[req->num]; - for (t = 0; t < genwqe_ddcb_software_timeout * 10; t++) { + for (t = 0; t < GENWQE_DDCB_SOFTWARE_TIMEOUT * 10; t++) { spin_lock_irqsave(&queue->ddcb_lock, flags); @@ -718,7 +718,7 @@ go_home: dev_err(&pci_dev->dev, "[%s] err: DDCB#%d not purged and not completed after %d seconds QSTAT=%016llx!!\n", - __func__, req->num, genwqe_ddcb_software_timeout, + __func__, req->num, GENWQE_DDCB_SOFTWARE_TIMEOUT, queue_status); print_ddcb_info(cd, req->queue); @@ -778,7 +778,7 @@ int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req, /* FIXME circumvention to improve performance when no irq is * there. */ - if (genwqe_polling_enabled) + if (GENWQE_POLLING_ENABLED) genwqe_check_ddcb_queue(cd, queue); /* @@ -878,7 +878,7 @@ int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req, pddcb->icrc_hsi_shi_32 = cpu_to_be32((u32)icrc << 16); /* enable DDCB completion irq */ - if (!genwqe_polling_enabled) + if (!GENWQE_POLLING_ENABLED) pddcb->icrc_hsi_shi_32 |= DDCB_INTR_BE32; dev_dbg(&pci_dev->dev, "INPUT DDCB#%d\n", req->num); @@ -1028,10 +1028,10 @@ static int setup_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue) unsigned int queue_size; struct pci_dev *pci_dev = cd->pci_dev; - if (genwqe_ddcb_max < 2) + if (GENWQE_DDCB_MAX < 2) return -EINVAL; - queue_size = roundup(genwqe_ddcb_max * sizeof(struct ddcb), PAGE_SIZE); + queue_size = roundup(GENWQE_DDCB_MAX * sizeof(struct ddcb), PAGE_SIZE); queue->ddcbs_in_flight = 0; /* statistics */ queue->ddcbs_max_in_flight = 0; @@ -1040,7 +1040,7 @@ static int setup_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue) queue->wait_on_busy = 0; queue->ddcb_seq = 0x100; /* start sequence number */ - queue->ddcb_max = genwqe_ddcb_max; /* module parameter */ + queue->ddcb_max = GENWQE_DDCB_MAX; queue->ddcb_vaddr = __genwqe_alloc_consistent(cd, queue_size, &queue->ddcb_daddr); if (queue->ddcb_vaddr == NULL) { @@ -1194,7 +1194,7 @@ static int genwqe_card_thread(void *data) genwqe_check_ddcb_queue(cd, &cd->queue); - if (genwqe_polling_enabled) { + if (GENWQE_POLLING_ENABLED) { rc = wait_event_interruptible_timeout( cd->queue_waitq, genwqe_ddcbs_in_flight(cd) || @@ -1340,7 +1340,7 @@ static int queue_wake_up_all(struct genwqe_dev *cd) int genwqe_finish_queue(struct genwqe_dev *cd) { int i, rc = 0, in_flight; - int waitmax = genwqe_ddcb_software_timeout; + int waitmax = GENWQE_DDCB_SOFTWARE_TIMEOUT; struct pci_dev *pci_dev = cd->pci_dev; struct ddcb_queue *queue = &cd->queue; diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c index c715534e7fe7..f921dd590271 100644 --- a/drivers/misc/genwqe/card_debugfs.c +++ b/drivers/misc/genwqe/card_debugfs.c @@ -198,7 +198,7 @@ static int genwqe_jtimer_show(struct seq_file *s, void *unused) jtimer = genwqe_read_vreg(cd, IO_SLC_VF_APPJOB_TIMEOUT, 0); seq_printf(s, " PF 0x%016llx %d msec\n", jtimer, - genwqe_pf_jobtimeout_msec); + GENWQE_PF_JOBTIMEOUT_MSEC); for (vf_num = 0; vf_num < cd->num_vfs; vf_num++) { jtimer = genwqe_read_vreg(cd, IO_SLC_VF_APPJOB_TIMEOUT, diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 3ecfa35457e0..0dd6b5ef314a 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -226,7 +226,7 @@ static void genwqe_remove_mappings(struct genwqe_file *cfile) kfree(dma_map); } else if (dma_map->type == GENWQE_MAPPING_SGL_TEMP) { /* we use dma_map statically from the request */ - genwqe_user_vunmap(cd, dma_map, NULL); + genwqe_user_vunmap(cd, dma_map); } } } @@ -249,7 +249,7 @@ static void genwqe_remove_pinnings(struct genwqe_file *cfile) * deleted. */ list_del_init(&dma_map->pin_list); - genwqe_user_vunmap(cd, dma_map, NULL); + genwqe_user_vunmap(cd, dma_map); kfree(dma_map); } } @@ -790,7 +790,7 @@ static int genwqe_pin_mem(struct genwqe_file *cfile, struct genwqe_mem *m) return -ENOMEM; genwqe_mapping_init(dma_map, GENWQE_MAPPING_SGL_PINNED); - rc = genwqe_user_vmap(cd, dma_map, (void *)map_addr, map_size, NULL); + rc = genwqe_user_vmap(cd, dma_map, (void *)map_addr, map_size); if (rc != 0) { dev_err(&pci_dev->dev, "[%s] genwqe_user_vmap rc=%d\n", __func__, rc); @@ -820,7 +820,7 @@ static int genwqe_unpin_mem(struct genwqe_file *cfile, struct genwqe_mem *m) return -ENOENT; genwqe_del_pin(cfile, dma_map); - genwqe_user_vunmap(cd, dma_map, NULL); + genwqe_user_vunmap(cd, dma_map); kfree(dma_map); return 0; } @@ -841,7 +841,7 @@ static int ddcb_cmd_cleanup(struct genwqe_file *cfile, struct ddcb_requ *req) if (dma_mapping_used(dma_map)) { __genwqe_del_mapping(cfile, dma_map); - genwqe_user_vunmap(cd, dma_map, req); + genwqe_user_vunmap(cd, dma_map); } if (req->sgls[i].sgl != NULL) genwqe_free_sync_sgl(cd, &req->sgls[i]); @@ -947,7 +947,7 @@ static int ddcb_cmd_fixups(struct genwqe_file *cfile, struct ddcb_requ *req) m->write = 0; rc = genwqe_user_vmap(cd, m, (void *)u_addr, - u_size, req); + u_size); if (rc != 0) goto err_out; @@ -1011,7 +1011,6 @@ static int do_execute_ddcb(struct genwqe_file *cfile, { int rc; struct genwqe_ddcb_cmd *cmd; - struct ddcb_requ *req; struct genwqe_dev *cd = cfile->cd; struct file *filp = cfile->filp; @@ -1019,8 +1018,6 @@ static int do_execute_ddcb(struct genwqe_file *cfile, if (cmd == NULL) return -ENOMEM; - req = container_of(cmd, struct ddcb_requ, cmd); - if (copy_from_user(cmd, (void __user *)arg, sizeof(*cmd))) { ddcb_requ_free(cmd); return -EFAULT; @@ -1345,7 +1342,7 @@ static int genwqe_inform_and_stop_processes(struct genwqe_dev *cd) rc = genwqe_kill_fasync(cd, SIGIO); if (rc > 0) { /* give kill_timeout seconds to close file descriptors ... */ - for (i = 0; (i < genwqe_kill_timeout) && + for (i = 0; (i < GENWQE_KILL_TIMEOUT) && genwqe_open_files(cd); i++) { dev_info(&pci_dev->dev, " %d sec ...", i); @@ -1363,7 +1360,7 @@ static int genwqe_inform_and_stop_processes(struct genwqe_dev *cd) rc = genwqe_force_sig(cd, SIGKILL); /* force terminate */ if (rc) { /* Give kill_timout more seconds to end processes */ - for (i = 0; (i < genwqe_kill_timeout) && + for (i = 0; (i < GENWQE_KILL_TIMEOUT) && genwqe_open_files(cd); i++) { dev_warn(&pci_dev->dev, " %d sec ...", i); diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index 5c0d917636f7..8f2e6442d88b 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -524,22 +524,16 @@ int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl) } /** - * free_user_pages() - Give pinned pages back + * genwqe_free_user_pages() - Give pinned pages back * - * Documentation of get_user_pages is in mm/memory.c: + * Documentation of get_user_pages is in mm/gup.c: * * If the page is written to, set_page_dirty (or set_page_dirty_lock, * as appropriate) must be called after the page is finished with, and * before put_page is called. - * - * FIXME Could be of use to others and might belong in the generic - * code, if others agree. E.g. - * ll_free_user_pages in drivers/staging/lustre/lustre/llite/rw26.c - * ceph_put_page_vector in net/ceph/pagevec.c - * maybe more? */ -static int free_user_pages(struct page **page_list, unsigned int nr_pages, - int dirty) +static int genwqe_free_user_pages(struct page **page_list, + unsigned int nr_pages, int dirty) { unsigned int i; @@ -577,7 +571,7 @@ static int free_user_pages(struct page **page_list, unsigned int nr_pages, * Return: 0 if success */ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, void *uaddr, - unsigned long size, struct ddcb_requ *req) + unsigned long size) { int rc = -EINVAL; unsigned long data, offs; @@ -617,7 +611,7 @@ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, void *uaddr, /* assumption: get_user_pages can be killed by signals. */ if (rc < m->nr_pages) { - free_user_pages(m->page_list, rc, m->write); + genwqe_free_user_pages(m->page_list, rc, m->write); rc = -EFAULT; goto fail_get_user_pages; } @@ -629,7 +623,7 @@ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, void *uaddr, return 0; fail_free_user_pages: - free_user_pages(m->page_list, m->nr_pages, m->write); + genwqe_free_user_pages(m->page_list, m->nr_pages, m->write); fail_get_user_pages: kfree(m->page_list); @@ -647,8 +641,7 @@ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, void *uaddr, * @cd: pointer to genwqe device * @m: mapping params */ -int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m, - struct ddcb_requ *req) +int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m) { struct pci_dev *pci_dev = cd->pci_dev; @@ -662,7 +655,7 @@ int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m, genwqe_unmap_pages(cd, m->dma_list, m->nr_pages); if (m->page_list) { - free_user_pages(m->page_list, m->nr_pages, m->write); + genwqe_free_user_pages(m->page_list, m->nr_pages, m->write); kfree(m->page_list); m->page_list = NULL; diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 95ce3e891b1b..35693c0a78e2 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the HP iLO management processor. * * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. * David Altobelli <david.altobelli@hpe.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/kernel.h> #include <linux/types.h> diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h index b97672e0cf90..94dfb9e40e29 100644 --- a/drivers/misc/hpilo.h +++ b/drivers/misc/hpilo.h @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/drivers/char/hpilo.h * * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. * David Altobelli <david.altobelli@hp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __HPILO_H #define __HPILO_H diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c index 28f51e01fd2b..81a0541ef3ac 100644 --- a/drivers/misc/ics932s401.c +++ b/drivers/misc/ics932s401.c @@ -33,7 +33,7 @@ static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END }; /* ICS932S401 registers */ #define ICS932S401_REG_CFG2 0x01 -#define ICS932S401_CFG1_SPREAD 0x01 +#define ICS932S401_CFG1_SPREAD 0x01 #define ICS932S401_REG_CFG7 0x06 #define ICS932S401_FS_MASK 0x07 #define ICS932S401_REG_VENDOR_REV 0x07 @@ -58,7 +58,7 @@ static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END }; #define ICS932S401_REG_SRC_SPREAD1 0x11 #define ICS932S401_REG_SRC_SPREAD2 0x12 #define ICS932S401_REG_CPU_DIVISOR 0x13 -#define ICS932S401_CPU_DIVISOR_SHIFT 4 +#define ICS932S401_CPU_DIVISOR_SHIFT 4 #define ICS932S401_REG_PCISRC_DIVISOR 0x14 #define ICS932S401_SRC_DIVISOR_MASK 0x0F #define ICS932S401_PCI_DIVISOR_SHIFT 4 @@ -225,6 +225,7 @@ static ssize_t show_cpu_clock_sel(struct device *dev, else { /* Freq is neatly wrapped up for us */ int fid = data->regs[ICS932S401_REG_CFG7] & ICS932S401_FS_MASK; + freq = fs_speeds[fid]; if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT) { switch (freq) { @@ -352,8 +353,7 @@ static DEVICE_ATTR(ref_clock, S_IRUGO, show_value, NULL); static DEVICE_ATTR(cpu_spread, S_IRUGO, show_spread, NULL); static DEVICE_ATTR(src_spread, S_IRUGO, show_spread, NULL); -static struct attribute *ics932s401_attr[] = -{ +static struct attribute *ics932s401_attr[] = { &dev_attr_spread_enabled.attr, &dev_attr_cpu_clock_selection.attr, &dev_attr_cpu_clock.attr, diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index 976df0013633..b8032882c865 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -78,6 +78,7 @@ static int __isl29003_read_reg(struct i2c_client *client, u32 reg, u8 mask, u8 shift) { struct isl29003_data *data = i2c_get_clientdata(client); + return (data->reg_cache[reg] & mask) >> shift; } @@ -160,6 +161,7 @@ static int isl29003_get_power_state(struct i2c_client *client) { struct isl29003_data *data = i2c_get_clientdata(client); u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND]; + return ~cmdreg & ISL29003_ADC_PD; } @@ -196,6 +198,7 @@ static ssize_t isl29003_show_range(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); + return sprintf(buf, "%i\n", isl29003_get_range(client)); } @@ -231,6 +234,7 @@ static ssize_t isl29003_show_resolution(struct device *dev, char *buf) { struct i2c_client *client = to_i2c_client(dev); + return sprintf(buf, "%d\n", isl29003_get_resolution(client)); } @@ -264,6 +268,7 @@ static ssize_t isl29003_show_mode(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); + return sprintf(buf, "%d\n", isl29003_get_mode(client)); } @@ -298,6 +303,7 @@ static ssize_t isl29003_show_power_state(struct device *dev, char *buf) { struct i2c_client *client = to_i2c_client(dev); + return sprintf(buf, "%d\n", isl29003_get_power_state(client)); } @@ -361,6 +367,7 @@ static int isl29003_init_client(struct i2c_client *client) * if one of the reads fails, we consider the init failed */ for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) { int v = i2c_smbus_read_byte_data(client, i); + if (v < 0) return -ENODEV; diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index ba92291508dc..4942da93d066 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c @@ -96,7 +96,7 @@ static struct crashpoint crashpoints[] = { CRASHPOINT("DIRECT", NULL), #ifdef CONFIG_KPROBES CRASHPOINT("INT_HARDWARE_ENTRY", "do_IRQ"), - CRASHPOINT("INT_HW_IRQ_EN", "handle_IRQ_event"), + CRASHPOINT("INT_HW_IRQ_EN", "handle_irq_event"), CRASHPOINT("INT_TASKLET_ENTRY", "tasklet_action"), CRASHPOINT("FS_DEVRW", "ll_rw_block"), CRASHPOINT("MEM_SWAPOUT", "shrink_inactive_list"), diff --git a/drivers/misc/lkdtm_heap.c b/drivers/misc/lkdtm_heap.c index f5494a6d4be5..65026d7de130 100644 --- a/drivers/misc/lkdtm_heap.c +++ b/drivers/misc/lkdtm_heap.c @@ -16,6 +16,8 @@ void lkdtm_OVERWRITE_ALLOCATION(void) { size_t len = 1020; u32 *data = kmalloc(len, GFP_KERNEL); + if (!data) + return; data[1024 / sizeof(u32)] = 0x12345678; kfree(data); @@ -33,6 +35,8 @@ void lkdtm_WRITE_AFTER_FREE(void) size_t offset = (len / sizeof(*base)) / 2; base = kmalloc(len, GFP_KERNEL); + if (!base) + return; pr_info("Allocated memory %p-%p\n", base, &base[offset * 2]); pr_info("Attempting bad write to freed memory at %p\n", &base[offset]); diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 1ac10cb64d6e..3e5eabdae8d9 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -543,14 +543,20 @@ int mei_cldev_disable(struct mei_cl_device *cldev) mutex_lock(&bus->device_lock); if (!mei_cl_is_connected(cl)) { - dev_dbg(bus->dev, "Already disconnected"); + dev_dbg(bus->dev, "Already disconnected\n"); + err = 0; + goto out; + } + + if (bus->dev_state == MEI_DEV_POWER_DOWN) { + dev_dbg(bus->dev, "Device is powering down, don't bother with disconnection\n"); err = 0; goto out; } err = mei_cl_disconnect(cl); if (err < 0) - dev_err(bus->dev, "Could not disconnect from the ME client"); + dev_err(bus->dev, "Could not disconnect from the ME client\n"); out: /* Flush queues and remove any pending read */ diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 10dcf4ff99a5..334ab02e1de2 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -1260,7 +1260,9 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) if (rets == -ENODATA) break; - if (rets && dev->dev_state != MEI_DEV_RESETTING) { + if (rets && + (dev->dev_state != MEI_DEV_RESETTING && + dev->dev_state != MEI_DEV_POWER_DOWN)) { dev_err(dev->dev, "mei_irq_read_handler ret = %d.\n", rets); schedule_work(&dev->reset_work); diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index 24e4a4c96606..c2c8993e2a51 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -1127,7 +1127,9 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) if (test_and_clear_bit(TXE_INTR_OUT_DB_BIT, &hw->intr_cause)) { /* Read from TXE */ rets = mei_irq_read_handler(dev, &cmpl_list, &slots); - if (rets && dev->dev_state != MEI_DEV_RESETTING) { + if (rets && + (dev->dev_state != MEI_DEV_RESETTING && + dev->dev_state != MEI_DEV_POWER_DOWN)) { dev_err(dev->dev, "mei_irq_read_handler ret = %d.\n", rets); diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index d2f691424dd1..c46f6e99a55e 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -310,6 +310,9 @@ void mei_stop(struct mei_device *dev) { dev_dbg(dev->dev, "stopping the device.\n"); + mutex_lock(&dev->device_lock); + dev->dev_state = MEI_DEV_POWER_DOWN; + mutex_unlock(&dev->device_lock); mei_cl_bus_remove_devices(dev); mei_cancel_work(dev); @@ -319,7 +322,6 @@ void mei_stop(struct mei_device *dev) mutex_lock(&dev->device_lock); - dev->dev_state = MEI_DEV_POWER_DOWN; mei_reset(dev); /* move device to disabled state unconditionally */ dev->dev_state = MEI_DEV_DISABLED; diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index f4f17552c9b8..4a0ccda4d04b 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -238,8 +238,11 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) */ mei_me_set_pm_domain(dev); - if (mei_pg_is_enabled(dev)) + if (mei_pg_is_enabled(dev)) { pm_runtime_put_noidle(&pdev->dev); + if (hw->d0i3_supported) + pm_runtime_allow(&pdev->dev); + } dev_dbg(&pdev->dev, "initialization successful.\n"); diff --git a/drivers/misc/mic/vop/vop_vringh.c b/drivers/misc/mic/vop/vop_vringh.c index 4120ed8f0cae..01d1f2ba7bb8 100644 --- a/drivers/misc/mic/vop/vop_vringh.c +++ b/drivers/misc/mic/vop/vop_vringh.c @@ -937,13 +937,10 @@ static long vop_ioctl(struct file *f, unsigned int cmd, unsigned long arg) dd.num_vq > MIC_MAX_VRINGS) return -EINVAL; - dd_config = kzalloc(mic_desc_size(&dd), GFP_KERNEL); - if (!dd_config) - return -ENOMEM; - if (copy_from_user(dd_config, argp, mic_desc_size(&dd))) { - ret = -EFAULT; - goto free_ret; - } + dd_config = memdup_user(argp, mic_desc_size(&dd)); + if (IS_ERR(dd_config)) + return PTR_ERR(dd_config); + /* Ensure desc has not changed between the two reads */ if (memcmp(&dd, dd_config, sizeof(dd))) { ret = -EINVAL; @@ -995,17 +992,12 @@ _unlock_ret: ret = vop_vdev_inited(vdev); if (ret) goto __unlock_ret; - buf = kzalloc(vdev->dd->config_len, GFP_KERNEL); - if (!buf) { - ret = -ENOMEM; + buf = memdup_user(argp, vdev->dd->config_len); + if (IS_ERR(buf)) { + ret = PTR_ERR(buf); goto __unlock_ret; } - if (copy_from_user(buf, argp, vdev->dd->config_len)) { - ret = -EFAULT; - goto done; - } ret = vop_virtio_config_change(vdev, buf); -done: kfree(buf); __unlock_ret: mutex_unlock(&vdev->vdev_mutex); diff --git a/drivers/misc/vexpress-syscfg.c b/drivers/misc/vexpress-syscfg.c index 2cde80c7bb93..9eea30f54fd6 100644 --- a/drivers/misc/vexpress-syscfg.c +++ b/drivers/misc/vexpress-syscfg.c @@ -270,10 +270,8 @@ static int vexpress_syscfg_probe(struct platform_device *pdev) /* Must use dev.parent (MFD), as that's where DT phandle points at... */ bridge = vexpress_config_bridge_register(pdev->dev.parent, &vexpress_syscfg_bridge_ops, syscfg); - if (IS_ERR(bridge)) - return PTR_ERR(bridge); - return 0; + return PTR_ERR_OR_ZERO(bridge); } static const struct platform_device_id vexpress_syscfg_id_table[] = { |