Commit d3feaff4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'char-misc-6.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc driver fixes from Greg KH:
 "Here are a number of small char/misc/whatever driver fixes. They
  include:

   - IIO driver fixes for some reported problems

   - nvmem driver fixes

   - fpga driver fixes

   - debugfs memory leak fix in the hv_balloon and irqdomain code
     (irqdomain change was acked by the maintainer)

  All have been in linux-next with no reported problems"

* tag 'char-misc-6.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (33 commits)
  kernel/irq/irqdomain.c: fix memory leak with using debugfs_lookup()
  HV: hv_balloon: fix memory leak with using debugfs_lookup()
  nvmem: qcom-spmi-sdam: fix module autoloading
  nvmem: core: fix return value
  nvmem: core: fix cell removal on error
  nvmem: core: fix device node refcounting
  nvmem: core: fix registration vs use race
  nvmem: core: fix cleanup after dev_set_name()
  nvmem: core: remove nvmem_config wp_gpio
  nvmem: core: initialise nvmem->id early
  nvmem: sunxi_sid: Always use 32-bit MMIO reads
  nvmem: brcm_nvram: Add check for kzalloc
  iio: imu: fxos8700: fix MAGN sensor scale and unit
  iio: imu: fxos8700: remove definition FXOS8700_CTRL_ODR_MIN
  iio: imu: fxos8700: fix failed initialization ODR mode assignment
  iio: imu: fxos8700: fix incorrect ODR mode readback
  iio: light: cm32181: Fix PM support on system with 2 I2C resources
  iio: hid: fix the retval in gyro_3d_capture_sample
  iio: hid: fix the retval in accel_3d_capture_sample
  iio: imu: st_lsm6dsx: fix build when CONFIG_IIO_TRIGGERED_BUFFER=m
  ...
parents 870c3a9a d83d7ed2
...@@ -574,20 +574,27 @@ static int m10bmc_sec_probe(struct platform_device *pdev) ...@@ -574,20 +574,27 @@ static int m10bmc_sec_probe(struct platform_device *pdev)
len = scnprintf(buf, SEC_UPDATE_LEN_MAX, "secure-update%d", len = scnprintf(buf, SEC_UPDATE_LEN_MAX, "secure-update%d",
sec->fw_name_id); sec->fw_name_id);
sec->fw_name = kmemdup_nul(buf, len, GFP_KERNEL); sec->fw_name = kmemdup_nul(buf, len, GFP_KERNEL);
if (!sec->fw_name) if (!sec->fw_name) {
return -ENOMEM; ret = -ENOMEM;
goto fw_name_fail;
}
fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name, fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name,
&m10bmc_ops, sec); &m10bmc_ops, sec);
if (IS_ERR(fwl)) { if (IS_ERR(fwl)) {
dev_err(sec->dev, "Firmware Upload driver failed to start\n"); dev_err(sec->dev, "Firmware Upload driver failed to start\n");
kfree(sec->fw_name); ret = PTR_ERR(fwl);
xa_erase(&fw_upload_xa, sec->fw_name_id); goto fw_uploader_fail;
return PTR_ERR(fwl);
} }
sec->fwl = fwl; sec->fwl = fwl;
return 0; return 0;
fw_uploader_fail:
kfree(sec->fw_name);
fw_name_fail:
xa_erase(&fw_upload_xa, sec->fw_name_id);
return ret;
} }
static int m10bmc_sec_remove(struct platform_device *pdev) static int m10bmc_sec_remove(struct platform_device *pdev)
......
...@@ -213,9 +213,9 @@ static int s10_ops_write_init(struct fpga_manager *mgr, ...@@ -213,9 +213,9 @@ static int s10_ops_write_init(struct fpga_manager *mgr,
/* Allocate buffers from the service layer's pool. */ /* Allocate buffers from the service layer's pool. */
for (i = 0; i < NUM_SVC_BUFS; i++) { for (i = 0; i < NUM_SVC_BUFS; i++) {
kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE); kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE);
if (!kbuf) { if (IS_ERR(kbuf)) {
s10_free_buffers(mgr); s10_free_buffers(mgr);
ret = -ENOMEM; ret = PTR_ERR(kbuf);
goto init_done; goto init_done;
} }
......
...@@ -1963,7 +1963,7 @@ static void hv_balloon_debugfs_init(struct hv_dynmem_device *b) ...@@ -1963,7 +1963,7 @@ static void hv_balloon_debugfs_init(struct hv_dynmem_device *b)
static void hv_balloon_debugfs_exit(struct hv_dynmem_device *b) static void hv_balloon_debugfs_exit(struct hv_dynmem_device *b)
{ {
debugfs_remove(debugfs_lookup("hv-balloon", NULL)); debugfs_lookup_and_remove("hv-balloon", NULL);
} }
#else #else
......
...@@ -280,6 +280,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev, ...@@ -280,6 +280,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
hid_sensor_convert_timestamp( hid_sensor_convert_timestamp(
&accel_state->common_attributes, &accel_state->common_attributes,
*(int64_t *)raw_data); *(int64_t *)raw_data);
ret = 0;
break; break;
default: default:
break; break;
......
...@@ -298,8 +298,10 @@ static int berlin2_adc_probe(struct platform_device *pdev) ...@@ -298,8 +298,10 @@ static int berlin2_adc_probe(struct platform_device *pdev)
int ret; int ret;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
if (!indio_dev) if (!indio_dev) {
of_node_put(parent_np);
return -ENOMEM; return -ENOMEM;
}
priv = iio_priv(indio_dev); priv = iio_priv(indio_dev);
......
...@@ -86,6 +86,8 @@ ...@@ -86,6 +86,8 @@
#define IMX8QXP_ADC_TIMEOUT msecs_to_jiffies(100) #define IMX8QXP_ADC_TIMEOUT msecs_to_jiffies(100)
#define IMX8QXP_ADC_MAX_FIFO_SIZE 16
struct imx8qxp_adc { struct imx8qxp_adc {
struct device *dev; struct device *dev;
void __iomem *regs; void __iomem *regs;
...@@ -95,6 +97,7 @@ struct imx8qxp_adc { ...@@ -95,6 +97,7 @@ struct imx8qxp_adc {
/* Serialise ADC channel reads */ /* Serialise ADC channel reads */
struct mutex lock; struct mutex lock;
struct completion completion; struct completion completion;
u32 fifo[IMX8QXP_ADC_MAX_FIFO_SIZE];
}; };
#define IMX8QXP_ADC_CHAN(_idx) { \ #define IMX8QXP_ADC_CHAN(_idx) { \
...@@ -238,8 +241,7 @@ static int imx8qxp_adc_read_raw(struct iio_dev *indio_dev, ...@@ -238,8 +241,7 @@ static int imx8qxp_adc_read_raw(struct iio_dev *indio_dev,
return ret; return ret;
} }
*val = FIELD_GET(IMX8QXP_ADC_RESFIFO_VAL_MASK, *val = adc->fifo[0];
readl(adc->regs + IMX8QXP_ADR_ADC_RESFIFO));
mutex_unlock(&adc->lock); mutex_unlock(&adc->lock);
return IIO_VAL_INT; return IIO_VAL_INT;
...@@ -265,10 +267,15 @@ static irqreturn_t imx8qxp_adc_isr(int irq, void *dev_id) ...@@ -265,10 +267,15 @@ static irqreturn_t imx8qxp_adc_isr(int irq, void *dev_id)
{ {
struct imx8qxp_adc *adc = dev_id; struct imx8qxp_adc *adc = dev_id;
u32 fifo_count; u32 fifo_count;
int i;
fifo_count = FIELD_GET(IMX8QXP_ADC_FCTRL_FCOUNT_MASK, fifo_count = FIELD_GET(IMX8QXP_ADC_FCTRL_FCOUNT_MASK,
readl(adc->regs + IMX8QXP_ADR_ADC_FCTRL)); readl(adc->regs + IMX8QXP_ADR_ADC_FCTRL));
for (i = 0; i < fifo_count; i++)
adc->fifo[i] = FIELD_GET(IMX8QXP_ADC_RESFIFO_VAL_MASK,
readl_relaxed(adc->regs + IMX8QXP_ADR_ADC_RESFIFO));
if (fifo_count) if (fifo_count)
complete(&adc->completion); complete(&adc->completion);
......
...@@ -1520,6 +1520,7 @@ static const struct of_device_id stm32_dfsdm_adc_match[] = { ...@@ -1520,6 +1520,7 @@ static const struct of_device_id stm32_dfsdm_adc_match[] = {
}, },
{} {}
}; };
MODULE_DEVICE_TABLE(of, stm32_dfsdm_adc_match);
static int stm32_dfsdm_adc_probe(struct platform_device *pdev) static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
{ {
......
...@@ -57,6 +57,18 @@ ...@@ -57,6 +57,18 @@
#define TWL6030_GPADCS BIT(1) #define TWL6030_GPADCS BIT(1)
#define TWL6030_GPADCR BIT(0) #define TWL6030_GPADCR BIT(0)
#define USB_VBUS_CTRL_SET 0x04
#define USB_ID_CTRL_SET 0x06
#define TWL6030_MISC1 0xE4
#define VBUS_MEAS 0x01
#define ID_MEAS 0x01
#define VAC_MEAS 0x04
#define VBAT_MEAS 0x02
#define BB_MEAS 0x01
/** /**
* struct twl6030_chnl_calib - channel calibration * struct twl6030_chnl_calib - channel calibration
* @gain: slope coefficient for ideal curve * @gain: slope coefficient for ideal curve
...@@ -927,6 +939,26 @@ static int twl6030_gpadc_probe(struct platform_device *pdev) ...@@ -927,6 +939,26 @@ static int twl6030_gpadc_probe(struct platform_device *pdev)
return ret; return ret;
} }
ret = twl_i2c_write_u8(TWL_MODULE_USB, VBUS_MEAS, USB_VBUS_CTRL_SET);
if (ret < 0) {
dev_err(dev, "failed to wire up inputs\n");
return ret;
}
ret = twl_i2c_write_u8(TWL_MODULE_USB, ID_MEAS, USB_ID_CTRL_SET);
if (ret < 0) {
dev_err(dev, "failed to wire up inputs\n");
return ret;
}
ret = twl_i2c_write_u8(TWL6030_MODULE_ID0,
VBAT_MEAS | BB_MEAS | VAC_MEAS,
TWL6030_MISC1);
if (ret < 0) {
dev_err(dev, "failed to wire up inputs\n");
return ret;
}
indio_dev->name = DRIVER_NAME; indio_dev->name = DRIVER_NAME;
indio_dev->info = &twl6030_gpadc_iio_info; indio_dev->info = &twl6030_gpadc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
......
...@@ -1329,7 +1329,7 @@ static int ams_parse_firmware(struct iio_dev *indio_dev) ...@@ -1329,7 +1329,7 @@ static int ams_parse_firmware(struct iio_dev *indio_dev)
dev_channels = devm_krealloc(dev, ams_channels, dev_size, GFP_KERNEL); dev_channels = devm_krealloc(dev, ams_channels, dev_size, GFP_KERNEL);
if (!dev_channels) if (!dev_channels)
ret = -ENOMEM; return -ENOMEM;
indio_dev->channels = dev_channels; indio_dev->channels = dev_channels;
indio_dev->num_channels = num_channels; indio_dev->num_channels = num_channels;
......
...@@ -231,6 +231,7 @@ static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev, ...@@ -231,6 +231,7 @@ static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
gyro_state->timestamp = gyro_state->timestamp =
hid_sensor_convert_timestamp(&gyro_state->common_attributes, hid_sensor_convert_timestamp(&gyro_state->common_attributes,
*(s64 *)raw_data); *(s64 *)raw_data);
ret = 0;
break; break;
default: default:
break; break;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/bitfield.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
...@@ -144,9 +145,8 @@ ...@@ -144,9 +145,8 @@
#define FXOS8700_NVM_DATA_BNK0 0xa7 #define FXOS8700_NVM_DATA_BNK0 0xa7
/* Bit definitions for FXOS8700_CTRL_REG1 */ /* Bit definitions for FXOS8700_CTRL_REG1 */
#define FXOS8700_CTRL_ODR_MSK 0x38
#define FXOS8700_CTRL_ODR_MAX 0x00 #define FXOS8700_CTRL_ODR_MAX 0x00
#define FXOS8700_CTRL_ODR_MIN GENMASK(4, 3) #define FXOS8700_CTRL_ODR_MSK GENMASK(5, 3)
/* Bit definitions for FXOS8700_M_CTRL_REG1 */ /* Bit definitions for FXOS8700_M_CTRL_REG1 */
#define FXOS8700_HMS_MASK GENMASK(1, 0) #define FXOS8700_HMS_MASK GENMASK(1, 0)
...@@ -320,7 +320,7 @@ static enum fxos8700_sensor fxos8700_to_sensor(enum iio_chan_type iio_type) ...@@ -320,7 +320,7 @@ static enum fxos8700_sensor fxos8700_to_sensor(enum iio_chan_type iio_type)
switch (iio_type) { switch (iio_type) {
case IIO_ACCEL: case IIO_ACCEL:
return FXOS8700_ACCEL; return FXOS8700_ACCEL;
case IIO_ANGL_VEL: case IIO_MAGN:
return FXOS8700_MAGN; return FXOS8700_MAGN;
default: default:
return -EINVAL; return -EINVAL;
...@@ -345,15 +345,35 @@ static int fxos8700_set_active_mode(struct fxos8700_data *data, ...@@ -345,15 +345,35 @@ static int fxos8700_set_active_mode(struct fxos8700_data *data,
static int fxos8700_set_scale(struct fxos8700_data *data, static int fxos8700_set_scale(struct fxos8700_data *data,
enum fxos8700_sensor t, int uscale) enum fxos8700_sensor t, int uscale)
{ {
int i; int i, ret, val;
bool active_mode;
static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale); static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
struct device *dev = regmap_get_device(data->regmap); struct device *dev = regmap_get_device(data->regmap);
if (t == FXOS8700_MAGN) { if (t == FXOS8700_MAGN) {
dev_err(dev, "Magnetometer scale is locked at 1200uT\n"); dev_err(dev, "Magnetometer scale is locked at 0.001Gs\n");
return -EINVAL; return -EINVAL;
} }
/*
* When device is in active mode, it failed to set an ACCEL
* full-scale range(2g/4g/8g) in FXOS8700_XYZ_DATA_CFG.
* This is not align with the datasheet, but it is a fxos8700
* chip behavier. Set the device in standby mode before setting
* an ACCEL full-scale range.
*/
ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
if (ret)
return ret;
active_mode = val & FXOS8700_ACTIVE;
if (active_mode) {
ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
val & ~FXOS8700_ACTIVE);
if (ret)
return ret;
}
for (i = 0; i < scale_num; i++) for (i = 0; i < scale_num; i++)
if (fxos8700_accel_scale[i].uscale == uscale) if (fxos8700_accel_scale[i].uscale == uscale)
break; break;
...@@ -361,8 +381,12 @@ static int fxos8700_set_scale(struct fxos8700_data *data, ...@@ -361,8 +381,12 @@ static int fxos8700_set_scale(struct fxos8700_data *data,
if (i == scale_num) if (i == scale_num)
return -EINVAL; return -EINVAL;
return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
fxos8700_accel_scale[i].bits); fxos8700_accel_scale[i].bits);
if (ret)
return ret;
return regmap_write(data->regmap, FXOS8700_CTRL_REG1,
active_mode);
} }
static int fxos8700_get_scale(struct fxos8700_data *data, static int fxos8700_get_scale(struct fxos8700_data *data,
...@@ -372,7 +396,7 @@ static int fxos8700_get_scale(struct fxos8700_data *data, ...@@ -372,7 +396,7 @@ static int fxos8700_get_scale(struct fxos8700_data *data,
static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale); static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
if (t == FXOS8700_MAGN) { if (t == FXOS8700_MAGN) {
*uscale = 1200; /* Magnetometer is locked at 1200uT */ *uscale = 1000; /* Magnetometer is locked at 0.001Gs */
return 0; return 0;
} }
...@@ -394,22 +418,61 @@ static int fxos8700_get_data(struct fxos8700_data *data, int chan_type, ...@@ -394,22 +418,61 @@ static int fxos8700_get_data(struct fxos8700_data *data, int chan_type,
int axis, int *val) int axis, int *val)
{ {
u8 base, reg; u8 base, reg;
s16 tmp;
int ret; int ret;
enum fxos8700_sensor type = fxos8700_to_sensor(chan_type);
base = type ? FXOS8700_OUT_X_MSB : FXOS8700_M_OUT_X_MSB; /*
* Different register base addresses varies with channel types.
* This bug hasn't been noticed before because using an enum is
* really hard to read. Use an a switch statement to take over that.
*/
switch (chan_type) {
case IIO_ACCEL:
base = FXOS8700_OUT_X_MSB;
break;
case IIO_MAGN:
base = FXOS8700_M_OUT_X_MSB;
break;
default:
return -EINVAL;
}
/* Block read 6 bytes of device output registers to avoid data loss */ /* Block read 6 bytes of device output registers to avoid data loss */
ret = regmap_bulk_read(data->regmap, base, data->buf, ret = regmap_bulk_read(data->regmap, base, data->buf,
FXOS8700_DATA_BUF_SIZE); sizeof(data->buf));
if (ret) if (ret)
return ret; return ret;
/* Convert axis to buffer index */ /* Convert axis to buffer index */
reg = axis - IIO_MOD_X; reg = axis - IIO_MOD_X;
/*
* Convert to native endianness. The accel data and magn data
* are signed, so a forced type conversion is needed.
*/
tmp = be16_to_cpu(data->buf[reg]);
/*
* ACCEL output data registers contain the X-axis, Y-axis, and Z-axis
* 14-bit left-justified sample data and MAGN output data registers
* contain the X-axis, Y-axis, and Z-axis 16-bit sample data. Apply
* a signed 2 bits right shift to the readback raw data from ACCEL
* output data register and keep that from MAGN sensor as the origin.
* Value should be extended to 32 bit.
*/
switch (chan_type) {
case IIO_ACCEL:
tmp = tmp >> 2;
break;
case IIO_MAGN:
/* Nothing to do */
break;
default:
return -EINVAL;
}
/* Convert to native endianness */ /* Convert to native endianness */
*val = sign_extend32(be16_to_cpu(data->buf[reg]), 15); *val = sign_extend32(tmp, 15);
return 0; return 0;
} }
...@@ -445,10 +508,9 @@ static int fxos8700_set_odr(struct fxos8700_data *data, enum fxos8700_sensor t, ...@@ -445,10 +508,9 @@ static int fxos8700_set_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
if (i >= odr_num) if (i >= odr_num)
return -EINVAL; return -EINVAL;
return regmap_update_bits(data->regmap, val &= ~FXOS8700_CTRL_ODR_MSK;
FXOS8700_CTRL_REG1, val |= FIELD_PREP(FXOS8700_CTRL_ODR_MSK, fxos8700_odr[i].bits) | FXOS8700_ACTIVE;
FXOS8700_CTRL_ODR_MSK + FXOS8700_ACTIVE, return regmap_write(data->regmap, FXOS8700_CTRL_REG1, val);
fxos8700_odr[i].bits << 3 | active_mode);
} }
static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t, static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
...@@ -461,7 +523,7 @@ static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t, ...@@ -461,7 +523,7 @@ static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
if (ret) if (ret)
return ret; return ret;
val &= FXOS8700_CTRL_ODR_MSK; val = FIELD_GET(FXOS8700_CTRL_ODR_MSK, val);
for (i = 0; i < odr_num; i++) for (i = 0; i < odr_num; i++)
if (val == fxos8700_odr[i].bits) if (val == fxos8700_odr[i].bits)
...@@ -526,7 +588,7 @@ static IIO_CONST_ATTR(in_accel_sampling_frequency_available, ...@@ -526,7 +588,7 @@ static IIO_CONST_ATTR(in_accel_sampling_frequency_available,
static IIO_CONST_ATTR(in_magn_sampling_frequency_available, static IIO_CONST_ATTR(in_magn_sampling_frequency_available,
"1.5625 6.25 12.5 50 100 200 400 800"); "1.5625 6.25 12.5 50 100 200 400 800");
static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976"); static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976");
static IIO_CONST_ATTR(in_magn_scale_available, "0.000001200"); static IIO_CONST_ATTR(in_magn_scale_available, "0.001000");
static struct attribute *fxos8700_attrs[] = { static struct attribute *fxos8700_attrs[] = {
&iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr, &iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr,
...@@ -592,14 +654,19 @@ static int fxos8700_chip_init(struct fxos8700_data *data, bool use_spi) ...@@ -592,14 +654,19 @@ static int fxos8700_chip_init(struct fxos8700_data *data, bool use_spi)
if (ret) if (ret)
return ret; return ret;
/* Max ODR (800Hz individual or 400Hz hybrid), active mode */ /*
ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, * Set max full-scale range (+/-8G) for ACCEL sensor in chip
FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE); * initialization then activate the device.
*/
ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
if (ret) if (ret)
return ret; return ret;
/* Set for max full-scale range (+/-8G) */ /* Max ODR (800Hz individual or 400Hz hybrid), active mode */
return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G); return regmap_update_bits(data->regmap, FXOS8700_CTRL_REG1,
FXOS8700_CTRL_ODR_MSK | FXOS8700_ACTIVE,
FIELD_PREP(FXOS8700_CTRL_ODR_MSK, FXOS8700_CTRL_ODR_MAX) |
FXOS8700_ACTIVE);
} }
static void fxos8700_chip_uninit(void *data) static void fxos8700_chip_uninit(void *data)
......
...@@ -4,6 +4,7 @@ config IIO_ST_LSM6DSX ...@@ -4,6 +4,7 @@ config IIO_ST_LSM6DSX
tristate "ST_LSM6DSx driver for STM 6-axis IMU MEMS sensors" tristate "ST_LSM6DSx driver for STM 6-axis IMU MEMS sensors"
depends on (I2C || SPI || I3C) depends on (I2C || SPI || I3C)
select IIO_BUFFER select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select IIO_KFIFO_BUF select IIO_KFIFO_BUF
select IIO_ST_LSM6DSX_I2C if (I2C) select IIO_ST_LSM6DSX_I2C if (I2C)
select IIO_ST_LSM6DSX_SPI if (SPI_MASTER) select IIO_ST_LSM6DSX_SPI if (SPI_MASTER)
......
...@@ -440,6 +440,8 @@ static int cm32181_probe(struct i2c_client *client) ...@@ -440,6 +440,8 @@ static int cm32181_probe(struct i2c_client *client)
if (!indio_dev) if (!indio_dev)
return -ENOMEM; return -ENOMEM;
i2c_set_clientdata(client, indio_dev);
/* /*
* Some ACPI systems list 2 I2C resources for the CM3218 sensor, the * Some ACPI systems list 2 I2C resources for the CM3218 sensor, the
* SMBus Alert Response Address (ARA, 0x0c) and the actual I2C address. * SMBus Alert Response Address (ARA, 0x0c) and the actual I2C address.
...@@ -460,8 +462,6 @@ static int cm32181_probe(struct i2c_client *client) ...@@ -460,8 +462,6 @@ static int cm32181_probe(struct i2c_client *client)
return PTR_ERR(client); return PTR_ERR(client);
} }
i2c_set_clientdata(client, indio_dev);
cm32181 = iio_priv(indio_dev); cm32181 = iio_priv(indio_dev);
cm32181->client = client; cm32181->client = client;
cm32181->dev = dev; cm32181->dev = dev;
...@@ -490,7 +490,8 @@ static int cm32181_probe(struct i2c_client *client) ...@@ -490,7 +490,8 @@ static int cm32181_probe(struct i2c_client *client)
static int cm32181_suspend(struct device *dev) static int cm32181_suspend(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev); struct cm32181_chip *cm32181 = iio_priv(dev_get_drvdata(dev));
struct i2c_client *client = cm32181->client;
return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD, return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
CM32181_CMD_ALS_DISABLE); CM32181_CMD_ALS_DISABLE);
...@@ -498,8 +499,8 @@ static int cm32181_suspend(struct device *dev) ...@@ -498,8 +499,8 @@ static int cm32181_suspend(struct device *dev)
static int cm32181_resume(struct device *dev) static int cm32181_resume(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct cm32181_chip *cm32181 = iio_priv(dev_get_drvdata(dev)); struct cm32181_chip *cm32181 = iio_priv(dev_get_drvdata(dev));
struct i2c_client *client = cm32181->client;
return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD, return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
cm32181->conf_regs[CM32181_REG_ADDR_CMD]); cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
......
...@@ -98,6 +98,9 @@ static int brcm_nvram_parse(struct brcm_nvram *priv) ...@@ -98,6 +98,9 @@ static int brcm_nvram_parse(struct brcm_nvram *priv)
len = le32_to_cpu(header.len); len = le32_to_cpu(header.len);
data = kzalloc(len, GFP_KERNEL); data = kzalloc(len, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy_fromio(data, priv->base, len); memcpy_fromio(data, priv->base, len);
data[len - 1] = '\0'; data[len - 1] = '\0';
......
...@@ -770,31 +770,32 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) ...@@ -770,31 +770,32 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
return ERR_PTR(rval); return ERR_PTR(rval);
} }
if (config->wp_gpio) nvmem->id = rval;
nvmem->wp_gpio = config->wp_gpio;
else if (!config->ignore_wp) nvmem->dev.type = &nvmem_provider_type;
nvmem->dev.bus = &nvmem_bus_type;
nvmem->dev.parent = config->dev;
device_initialize(&nvmem->dev);
if (!config->ignore_wp)
nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp",
GPIOD_OUT_HIGH); GPIOD_OUT_HIGH);
if (IS_ERR(nvmem->wp_gpio)) { if (IS_ERR(nvmem->wp_gpio)) {
ida_free(&nvmem_ida, nvmem->id);
rval = PTR_ERR(nvmem->wp_gpio); rval = PTR_ERR(nvmem->wp_gpio);
kfree(nvmem); nvmem->wp_gpio = NULL;
return ERR_PTR(rval); goto err_put_device;
} }
kref_init(&nvmem->refcnt); kref_init(&nvmem->refcnt);
INIT_LIST_HEAD(&nvmem->cells); INIT_LIST_HEAD(&nvmem->cells);
nvmem->id = rval;
nvmem->owner = config->owner; nvmem->owner = config->owner;
if (!nvmem->owner && config->dev->driver) if (!nvmem->owner && config->dev->driver)
nvmem->owner = config->dev->driver->owner; nvmem->owner = config->dev->driver->owner;
nvmem->stride = config->stride ?: 1; nvmem->stride = config->stride ?: 1;
nvmem->word_size = config->word_size ?: 1; nvmem->word_size = config->word_size ?: 1;
nvmem->size = config->size; nvmem->size = config->size;
nvmem->dev.type = &nvmem_provider_type;
nvmem->dev.bus = &nvmem_bus_type;
nvmem->dev.parent = config->dev;
nvmem->root_only = config->root_only; nvmem->root_only = config->root_only;
nvmem->priv = config->priv; nvmem->priv = config->priv;
nvmem->type = config->type; nvmem->type = config->type;
...@@ -822,11 +823,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) ...@@ -822,11 +823,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
break; break;
} }
if (rval) { if (rval)
ida_free(&nvmem_ida, nvmem->id); goto err_put_device;
kfree(nvmem);
return ERR_PTR(rval);
}
nvmem->read_only = device_property_present(config->dev, "read-only") || nvmem->read_only = device_property_present(config->dev, "read-only") ||
config->read_only || !nvmem->reg_write; config->read_only || !nvmem->reg_write;
...@@ -835,28 +833,22 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) ...@@ -835,28 +833,22 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
nvmem->dev.groups = nvmem_dev_groups; nvmem->dev.groups = nvmem_dev_groups;
#endif #endif
dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
rval = device_register(&nvmem->dev);
if (rval)
goto err_put_device;
if (nvmem->nkeepout) { if (nvmem->nkeepout) {
rval = nvmem_validate_keepouts(nvmem); rval = nvmem_validate_keepouts(nvmem);
if (rval) if (rval)
goto err_device_del; goto err_put_device;
} }
if (config->compat) { if (config->compat) {
rval = nvmem_sysfs_setup_compat(nvmem, config); rval = nvmem_sysfs_setup_compat(nvmem, config);
if (rval) if (rval)
goto err_device_del; goto err_put_device;
} }
if (config->cells) { if (config->cells) {
rval = nvmem_add_cells(nvmem, config->cells, config->ncells); rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
if (rval) if (rval)
goto err_teardown_compat; goto err_remove_cells;
} }
rval = nvmem_add_cells_from_table(nvmem); rval = nvmem_add_cells_from_table(nvmem);
...@@ -867,17 +859,20 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) ...@@ -867,17 +859,20 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
if (rval) if (rval)
goto err_remove_cells; goto err_remove_cells;
dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
rval = device_add(&nvmem->dev);
if (rval)
goto err_remove_cells;
blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
return nvmem; return nvmem;
err_remove_cells: err_remove_cells:
nvmem_device_remove_all_cells(nvmem); nvmem_device_remove_all_cells(nvmem);
err_teardown_compat:
if (config->compat) if (config->compat)
nvmem_sysfs_remove_compat(nvmem, config); nvmem_sysfs_remove_compat(nvmem, config);
err_device_del:
device_del(&nvmem->dev);
err_put_device: err_put_device:
put_device(&nvmem->dev); put_device(&nvmem->dev);
...@@ -1242,16 +1237,21 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id) ...@@ -1242,16 +1237,21 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
if (!cell_np) if (!cell_np)
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
nvmem_np = of_get_next_parent(cell_np); nvmem_np = of_get_parent(cell_np);
if (!nvmem_np) if (!nvmem_np) {
of_node_put(cell_np);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
}
nvmem = __nvmem_device_get(nvmem_np, device_match_of_node); nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
of_node_put(nvmem_np); of_node_put(nvmem_np);
if (IS_ERR(nvmem)) if (IS_ERR(nvmem)) {
of_node_put(cell_np);
return ERR_CAST(nvmem); return ERR_CAST(nvmem);
}
cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np); cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np);
of_node_put(cell_np);
if (!cell_entry) { if (!cell_entry) {
__nvmem_device_put(nvmem); __nvmem_device_put(nvmem);
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
......
...@@ -166,6 +166,7 @@ static const struct of_device_id sdam_match_table[] = { ...@@ -166,6 +166,7 @@ static const struct of_device_id sdam_match_table[] = {
{ .compatible = "qcom,spmi-sdam" }, { .compatible = "qcom,spmi-sdam" },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, sdam_match_table);
static struct platform_driver sdam_driver = { static struct platform_driver sdam_driver = {
.driver = { .driver = {
......
...@@ -41,8 +41,21 @@ static int sunxi_sid_read(void *context, unsigned int offset, ...@@ -41,8 +41,21 @@ static int sunxi_sid_read(void *context, unsigned int offset,
void *val, size_t bytes) void *val, size_t bytes)
{ {
struct sunxi_sid *sid = context; struct sunxi_sid *sid = context;
u32 word;
/* .stride = 4 so offset is guaranteed to be aligned */
__ioread32_copy(val, sid->base + sid->value_offset + offset, bytes / 4);
memcpy_fromio(val, sid->base + sid->value_offset + offset, bytes); val += round_down(bytes, 4);
offset += round_down(bytes, 4);
bytes = bytes % 4;
if (!bytes)
return 0;
/* Handle any trailing bytes */
word = readl_relaxed(sid->base + sid->value_offset + offset);
memcpy(val, &word, bytes);
return 0; return 0;
} }
......
...@@ -70,7 +70,6 @@ struct nvmem_keepout { ...@@ -70,7 +70,6 @@ struct nvmem_keepout {
* @word_size: Minimum read/write access granularity. * @word_size: Minimum read/write access granularity.
* @stride: Minimum read/write access stride. * @stride: Minimum read/write access stride.
* @priv: User context passed to read/write callbacks. * @priv: User context passed to read/write callbacks.
* @wp-gpio: Write protect pin
* @ignore_wp: Write Protect pin is managed by the provider. * @ignore_wp: Write Protect pin is managed by the provider.
* *
* Note: A default "nvmem<id>" name will be assigned to the device if * Note: A default "nvmem<id>" name will be assigned to the device if
...@@ -85,7 +84,6 @@ struct nvmem_config { ...@@ -85,7 +84,6 @@ struct nvmem_config {
const char *name; const char *name;
int id; int id;
struct module *owner; struct module *owner;
struct gpio_desc *wp_gpio;
const struct nvmem_cell_info *cells; const struct nvmem_cell_info *cells;
int ncells; int ncells;
const struct nvmem_keepout *keepout; const struct nvmem_keepout *keepout;
......
...@@ -1915,7 +1915,7 @@ static void debugfs_add_domain_dir(struct irq_domain *d) ...@@ -1915,7 +1915,7 @@ static void debugfs_add_domain_dir(struct irq_domain *d)
static void debugfs_remove_domain_dir(struct irq_domain *d) static void debugfs_remove_domain_dir(struct irq_domain *d)
{ {
debugfs_remove(debugfs_lookup(d->name, domain_dir)); debugfs_lookup_and_remove(d->name, domain_dir);
} }
void __init irq_domain_debugfs_init(struct dentry *root) void __init irq_domain_debugfs_init(struct dentry *root)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment