Commit 2fc5ddaa authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'stm-for-greg-20160420' of...

Merge tag 'stm-for-greg-20160420' of git://git.kernel.org/pub/scm/linux/kernel/git/ash/stm into char-misc-next

Alexander writes:

stm class/intel_th: Updates for 4.7

These are:
 * Intel TH/MSU: improved resource handling and releasing
 * Intel TH/MSU: rehashed locking around buffer accesses
 * Intel TH/outputs: better sysfs group handling
 * Intel TH, STM: various bugfixes and smaller improvements
 * Intel TH: added a PCI ID for Broxton-M SOC
parents 7553c7e6 aaa3ca82
...@@ -9754,6 +9754,7 @@ F: drivers/mmc/host/dw_mmc* ...@@ -9754,6 +9754,7 @@ F: drivers/mmc/host/dw_mmc*
SYSTEM TRACE MODULE CLASS SYSTEM TRACE MODULE CLASS
M: Alexander Shishkin <alexander.shishkin@linux.intel.com> M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
S: Maintained S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ash/stm.git
F: Documentation/trace/stm.txt F: Documentation/trace/stm.txt
F: drivers/hwtracing/stm/ F: drivers/hwtracing/stm/
F: include/linux/stm.h F: include/linux/stm.h
......
...@@ -71,6 +71,15 @@ static int intel_th_probe(struct device *dev) ...@@ -71,6 +71,15 @@ static int intel_th_probe(struct device *dev)
if (ret) if (ret)
return ret; return ret;
if (thdrv->attr_group) {
ret = sysfs_create_group(&thdev->dev.kobj, thdrv->attr_group);
if (ret) {
thdrv->remove(thdev);
return ret;
}
}
if (thdev->type == INTEL_TH_OUTPUT && if (thdev->type == INTEL_TH_OUTPUT &&
!intel_th_output_assigned(thdev)) !intel_th_output_assigned(thdev))
ret = hubdrv->assign(hub, thdev); ret = hubdrv->assign(hub, thdev);
...@@ -91,6 +100,9 @@ static int intel_th_remove(struct device *dev) ...@@ -91,6 +100,9 @@ static int intel_th_remove(struct device *dev)
return err; return err;
} }
if (thdrv->attr_group)
sysfs_remove_group(&thdev->dev.kobj, thdrv->attr_group);
thdrv->remove(thdev); thdrv->remove(thdev);
if (intel_th_output_assigned(thdev)) { if (intel_th_output_assigned(thdev)) {
...@@ -171,7 +183,14 @@ static DEVICE_ATTR_RO(port); ...@@ -171,7 +183,14 @@ static DEVICE_ATTR_RO(port);
static int intel_th_output_activate(struct intel_th_device *thdev) static int intel_th_output_activate(struct intel_th_device *thdev)
{ {
struct intel_th_driver *thdrv = to_intel_th_driver(thdev->dev.driver); struct intel_th_driver *thdrv =
to_intel_th_driver_or_null(thdev->dev.driver);
if (!thdrv)
return -ENODEV;
if (!try_module_get(thdrv->driver.owner))
return -ENODEV;
if (thdrv->activate) if (thdrv->activate)
return thdrv->activate(thdev); return thdrv->activate(thdev);
...@@ -183,12 +202,18 @@ static int intel_th_output_activate(struct intel_th_device *thdev) ...@@ -183,12 +202,18 @@ static int intel_th_output_activate(struct intel_th_device *thdev)
static void intel_th_output_deactivate(struct intel_th_device *thdev) static void intel_th_output_deactivate(struct intel_th_device *thdev)
{ {
struct intel_th_driver *thdrv = to_intel_th_driver(thdev->dev.driver); struct intel_th_driver *thdrv =
to_intel_th_driver_or_null(thdev->dev.driver);
if (!thdrv)
return;
if (thdrv->deactivate) if (thdrv->deactivate)
thdrv->deactivate(thdev); thdrv->deactivate(thdev);
else else
intel_th_trace_disable(thdev); intel_th_trace_disable(thdev);
module_put(thdrv->driver.owner);
} }
static ssize_t active_show(struct device *dev, struct device_attribute *attr, static ssize_t active_show(struct device *dev, struct device_attribute *attr,
......
...@@ -115,6 +115,7 @@ intel_th_output_assigned(struct intel_th_device *thdev) ...@@ -115,6 +115,7 @@ intel_th_output_assigned(struct intel_th_device *thdev)
* @enable: enable tracing for a given output device * @enable: enable tracing for a given output device
* @disable: disable tracing for a given output device * @disable: disable tracing for a given output device
* @fops: file operations for device nodes * @fops: file operations for device nodes
* @attr_group: attributes provided by the driver
* *
* Callbacks @probe and @remove are required for all device types. * Callbacks @probe and @remove are required for all device types.
* Switch device driver needs to fill in @assign, @enable and @disable * Switch device driver needs to fill in @assign, @enable and @disable
...@@ -139,6 +140,8 @@ struct intel_th_driver { ...@@ -139,6 +140,8 @@ struct intel_th_driver {
void (*deactivate)(struct intel_th_device *thdev); void (*deactivate)(struct intel_th_device *thdev);
/* file_operations for those who want a device node */ /* file_operations for those who want a device node */
const struct file_operations *fops; const struct file_operations *fops;
/* optional attributes */
struct attribute_group *attr_group;
/* source ops */ /* source ops */
int (*set_output)(struct intel_th_device *thdev, int (*set_output)(struct intel_th_device *thdev,
...@@ -148,6 +151,9 @@ struct intel_th_driver { ...@@ -148,6 +151,9 @@ struct intel_th_driver {
#define to_intel_th_driver(_d) \ #define to_intel_th_driver(_d) \
container_of((_d), struct intel_th_driver, driver) container_of((_d), struct intel_th_driver, driver)
#define to_intel_th_driver_or_null(_d) \
((_d) ? to_intel_th_driver(_d) : NULL)
static inline struct intel_th_device * static inline struct intel_th_device *
to_intel_th_hub(struct intel_th_device *thdev) to_intel_th_hub(struct intel_th_device *thdev)
{ {
......
...@@ -122,7 +122,6 @@ struct msc { ...@@ -122,7 +122,6 @@ struct msc {
atomic_t mmap_count; atomic_t mmap_count;
struct mutex buf_mutex; struct mutex buf_mutex;
struct mutex iter_mutex;
struct list_head iter_list; struct list_head iter_list;
/* config */ /* config */
...@@ -257,23 +256,37 @@ static struct msc_iter *msc_iter_install(struct msc *msc) ...@@ -257,23 +256,37 @@ static struct msc_iter *msc_iter_install(struct msc *msc)
iter = kzalloc(sizeof(*iter), GFP_KERNEL); iter = kzalloc(sizeof(*iter), GFP_KERNEL);
if (!iter) if (!iter)
return NULL; return ERR_PTR(-ENOMEM);
mutex_lock(&msc->buf_mutex);
/*
* Reading and tracing are mutually exclusive; if msc is
* enabled, open() will fail; otherwise existing readers
* will prevent enabling the msc and the rest of fops don't
* need to worry about it.
*/
if (msc->enabled) {
kfree(iter);
iter = ERR_PTR(-EBUSY);
goto unlock;
}
msc_iter_init(iter); msc_iter_init(iter);
iter->msc = msc; iter->msc = msc;
mutex_lock(&msc->iter_mutex);
list_add_tail(&iter->entry, &msc->iter_list); list_add_tail(&iter->entry, &msc->iter_list);
mutex_unlock(&msc->iter_mutex); unlock:
mutex_unlock(&msc->buf_mutex);
return iter; return iter;
} }
static void msc_iter_remove(struct msc_iter *iter, struct msc *msc) static void msc_iter_remove(struct msc_iter *iter, struct msc *msc)
{ {
mutex_lock(&msc->iter_mutex); mutex_lock(&msc->buf_mutex);
list_del(&iter->entry); list_del(&iter->entry);
mutex_unlock(&msc->iter_mutex); mutex_unlock(&msc->buf_mutex);
kfree(iter); kfree(iter);
} }
...@@ -454,7 +467,6 @@ static void msc_buffer_clear_hw_header(struct msc *msc) ...@@ -454,7 +467,6 @@ static void msc_buffer_clear_hw_header(struct msc *msc)
{ {
struct msc_window *win; struct msc_window *win;
mutex_lock(&msc->buf_mutex);
list_for_each_entry(win, &msc->win_list, entry) { list_for_each_entry(win, &msc->win_list, entry) {
unsigned int blk; unsigned int blk;
size_t hw_sz = sizeof(struct msc_block_desc) - size_t hw_sz = sizeof(struct msc_block_desc) -
...@@ -466,7 +478,6 @@ static void msc_buffer_clear_hw_header(struct msc *msc) ...@@ -466,7 +478,6 @@ static void msc_buffer_clear_hw_header(struct msc *msc)
memset(&bdesc->hw_tag, 0, hw_sz); memset(&bdesc->hw_tag, 0, hw_sz);
} }
} }
mutex_unlock(&msc->buf_mutex);
} }
/** /**
...@@ -474,12 +485,15 @@ static void msc_buffer_clear_hw_header(struct msc *msc) ...@@ -474,12 +485,15 @@ static void msc_buffer_clear_hw_header(struct msc *msc)
* @msc: the MSC device to configure * @msc: the MSC device to configure
* *
* Program storage mode, wrapping, burst length and trace buffer address * Program storage mode, wrapping, burst length and trace buffer address
* into a given MSC. If msc::enabled is set, enable the trace, too. * into a given MSC. Then, enable tracing and set msc::enabled.
* The latter is serialized on msc::buf_mutex, so make sure to hold it.
*/ */
static int msc_configure(struct msc *msc) static int msc_configure(struct msc *msc)
{ {
u32 reg; u32 reg;
lockdep_assert_held(&msc->buf_mutex);
if (msc->mode > MSC_MODE_MULTI) if (msc->mode > MSC_MODE_MULTI)
return -ENOTSUPP; return -ENOTSUPP;
...@@ -497,21 +511,19 @@ static int msc_configure(struct msc *msc) ...@@ -497,21 +511,19 @@ static int msc_configure(struct msc *msc)
reg = ioread32(msc->reg_base + REG_MSU_MSC0CTL); reg = ioread32(msc->reg_base + REG_MSU_MSC0CTL);
reg &= ~(MSC_MODE | MSC_WRAPEN | MSC_EN | MSC_RD_HDR_OVRD); reg &= ~(MSC_MODE | MSC_WRAPEN | MSC_EN | MSC_RD_HDR_OVRD);
reg |= MSC_EN;
reg |= msc->mode << __ffs(MSC_MODE); reg |= msc->mode << __ffs(MSC_MODE);
reg |= msc->burst_len << __ffs(MSC_LEN); reg |= msc->burst_len << __ffs(MSC_LEN);
/*if (msc->mode == MSC_MODE_MULTI)
reg |= MSC_RD_HDR_OVRD; */
if (msc->wrap) if (msc->wrap)
reg |= MSC_WRAPEN; reg |= MSC_WRAPEN;
if (msc->enabled)
reg |= MSC_EN;
iowrite32(reg, msc->reg_base + REG_MSU_MSC0CTL); iowrite32(reg, msc->reg_base + REG_MSU_MSC0CTL);
if (msc->enabled) { msc->thdev->output.multiblock = msc->mode == MSC_MODE_MULTI;
msc->thdev->output.multiblock = msc->mode == MSC_MODE_MULTI; intel_th_trace_enable(msc->thdev);
intel_th_trace_enable(msc->thdev); msc->enabled = 1;
}
return 0; return 0;
} }
...@@ -521,15 +533,14 @@ static int msc_configure(struct msc *msc) ...@@ -521,15 +533,14 @@ static int msc_configure(struct msc *msc)
* @msc: MSC device to disable * @msc: MSC device to disable
* *
* If @msc is enabled, disable tracing on the switch and then disable MSC * If @msc is enabled, disable tracing on the switch and then disable MSC
* storage. * storage. Caller must hold msc::buf_mutex.
*/ */
static void msc_disable(struct msc *msc) static void msc_disable(struct msc *msc)
{ {
unsigned long count; unsigned long count;
u32 reg; u32 reg;
if (!msc->enabled) lockdep_assert_held(&msc->buf_mutex);
return;
intel_th_trace_disable(msc->thdev); intel_th_trace_disable(msc->thdev);
...@@ -569,33 +580,35 @@ static void msc_disable(struct msc *msc) ...@@ -569,33 +580,35 @@ static void msc_disable(struct msc *msc)
static int intel_th_msc_activate(struct intel_th_device *thdev) static int intel_th_msc_activate(struct intel_th_device *thdev)
{ {
struct msc *msc = dev_get_drvdata(&thdev->dev); struct msc *msc = dev_get_drvdata(&thdev->dev);
int ret = 0; int ret = -EBUSY;
if (!atomic_inc_unless_negative(&msc->user_count)) if (!atomic_inc_unless_negative(&msc->user_count))
return -ENODEV; return -ENODEV;
mutex_lock(&msc->iter_mutex); mutex_lock(&msc->buf_mutex);
if (!list_empty(&msc->iter_list))
ret = -EBUSY;
mutex_unlock(&msc->iter_mutex);
if (ret) { /* if there are readers, refuse */
atomic_dec(&msc->user_count); if (list_empty(&msc->iter_list))
return ret; ret = msc_configure(msc);
}
msc->enabled = 1; mutex_unlock(&msc->buf_mutex);
if (ret)
atomic_dec(&msc->user_count);
return msc_configure(msc); return ret;
} }
static void intel_th_msc_deactivate(struct intel_th_device *thdev) static void intel_th_msc_deactivate(struct intel_th_device *thdev)
{ {
struct msc *msc = dev_get_drvdata(&thdev->dev); struct msc *msc = dev_get_drvdata(&thdev->dev);
msc_disable(msc); mutex_lock(&msc->buf_mutex);
if (msc->enabled) {
atomic_dec(&msc->user_count); msc_disable(msc);
atomic_dec(&msc->user_count);
}
mutex_unlock(&msc->buf_mutex);
} }
/** /**
...@@ -1035,8 +1048,8 @@ static int intel_th_msc_open(struct inode *inode, struct file *file) ...@@ -1035,8 +1048,8 @@ static int intel_th_msc_open(struct inode *inode, struct file *file)
return -EPERM; return -EPERM;
iter = msc_iter_install(msc); iter = msc_iter_install(msc);
if (!iter) if (IS_ERR(iter))
return -ENOMEM; return PTR_ERR(iter);
file->private_data = iter; file->private_data = iter;
...@@ -1101,11 +1114,6 @@ static ssize_t intel_th_msc_read(struct file *file, char __user *buf, ...@@ -1101,11 +1114,6 @@ static ssize_t intel_th_msc_read(struct file *file, char __user *buf,
if (!atomic_inc_unless_negative(&msc->user_count)) if (!atomic_inc_unless_negative(&msc->user_count))
return 0; return 0;
if (msc->enabled) {
ret = -EBUSY;
goto put_count;
}
if (msc->mode == MSC_MODE_SINGLE && !msc->single_wrap) if (msc->mode == MSC_MODE_SINGLE && !msc->single_wrap)
size = msc->single_sz; size = msc->single_sz;
else else
...@@ -1245,6 +1253,7 @@ static const struct file_operations intel_th_msc_fops = { ...@@ -1245,6 +1253,7 @@ static const struct file_operations intel_th_msc_fops = {
.read = intel_th_msc_read, .read = intel_th_msc_read,
.mmap = intel_th_msc_mmap, .mmap = intel_th_msc_mmap,
.llseek = no_llseek, .llseek = no_llseek,
.owner = THIS_MODULE,
}; };
static int intel_th_msc_init(struct msc *msc) static int intel_th_msc_init(struct msc *msc)
...@@ -1254,8 +1263,6 @@ static int intel_th_msc_init(struct msc *msc) ...@@ -1254,8 +1263,6 @@ static int intel_th_msc_init(struct msc *msc)
msc->mode = MSC_MODE_MULTI; msc->mode = MSC_MODE_MULTI;
mutex_init(&msc->buf_mutex); mutex_init(&msc->buf_mutex);
INIT_LIST_HEAD(&msc->win_list); INIT_LIST_HEAD(&msc->win_list);
mutex_init(&msc->iter_mutex);
INIT_LIST_HEAD(&msc->iter_list); INIT_LIST_HEAD(&msc->iter_list);
msc->burst_len = msc->burst_len =
...@@ -1393,6 +1400,11 @@ nr_pages_store(struct device *dev, struct device_attribute *attr, ...@@ -1393,6 +1400,11 @@ nr_pages_store(struct device *dev, struct device_attribute *attr,
do { do {
end = memchr(p, ',', len); end = memchr(p, ',', len);
s = kstrndup(p, end ? end - p : len, GFP_KERNEL); s = kstrndup(p, end ? end - p : len, GFP_KERNEL);
if (!s) {
ret = -ENOMEM;
goto free_win;
}
ret = kstrtoul(s, 10, &val); ret = kstrtoul(s, 10, &val);
kfree(s); kfree(s);
...@@ -1473,10 +1485,6 @@ static int intel_th_msc_probe(struct intel_th_device *thdev) ...@@ -1473,10 +1485,6 @@ static int intel_th_msc_probe(struct intel_th_device *thdev)
if (err) if (err)
return err; return err;
err = sysfs_create_group(&dev->kobj, &msc_output_group);
if (err)
return err;
dev_set_drvdata(dev, msc); dev_set_drvdata(dev, msc);
return 0; return 0;
...@@ -1484,7 +1492,18 @@ static int intel_th_msc_probe(struct intel_th_device *thdev) ...@@ -1484,7 +1492,18 @@ static int intel_th_msc_probe(struct intel_th_device *thdev)
static void intel_th_msc_remove(struct intel_th_device *thdev) static void intel_th_msc_remove(struct intel_th_device *thdev)
{ {
sysfs_remove_group(&thdev->dev.kobj, &msc_output_group); struct msc *msc = dev_get_drvdata(&thdev->dev);
int ret;
intel_th_msc_deactivate(thdev);
/*
* Buffers should not be used at this point except if the
* output character device is still open and the parent
* device gets detached from its bus, which is a FIXME.
*/
ret = msc_buffer_free_unless_used(msc);
WARN_ON_ONCE(ret);
} }
static struct intel_th_driver intel_th_msc_driver = { static struct intel_th_driver intel_th_msc_driver = {
...@@ -1493,6 +1512,7 @@ static struct intel_th_driver intel_th_msc_driver = { ...@@ -1493,6 +1512,7 @@ static struct intel_th_driver intel_th_msc_driver = {
.activate = intel_th_msc_activate, .activate = intel_th_msc_activate,
.deactivate = intel_th_msc_deactivate, .deactivate = intel_th_msc_deactivate,
.fops = &intel_th_msc_fops, .fops = &intel_th_msc_fops,
.attr_group = &msc_output_group,
.driver = { .driver = {
.name = "msc", .name = "msc",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -75,6 +75,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { ...@@ -75,6 +75,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80), PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80),
.driver_data = (kernel_ulong_t)0, .driver_data = (kernel_ulong_t)0,
}, },
{
/* Broxton B-step */
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e),
.driver_data = (kernel_ulong_t)0,
},
{ 0 }, { 0 },
}; };
......
...@@ -200,7 +200,6 @@ static int intel_th_pti_probe(struct intel_th_device *thdev) ...@@ -200,7 +200,6 @@ static int intel_th_pti_probe(struct intel_th_device *thdev)
struct resource *res; struct resource *res;
struct pti_device *pti; struct pti_device *pti;
void __iomem *base; void __iomem *base;
int ret;
res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 0); res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 0);
if (!res) if (!res)
...@@ -219,10 +218,6 @@ static int intel_th_pti_probe(struct intel_th_device *thdev) ...@@ -219,10 +218,6 @@ static int intel_th_pti_probe(struct intel_th_device *thdev)
read_hw_config(pti); read_hw_config(pti);
ret = sysfs_create_group(&dev->kobj, &pti_output_group);
if (ret)
return ret;
dev_set_drvdata(dev, pti); dev_set_drvdata(dev, pti);
return 0; return 0;
...@@ -237,6 +232,7 @@ static struct intel_th_driver intel_th_pti_driver = { ...@@ -237,6 +232,7 @@ static struct intel_th_driver intel_th_pti_driver = {
.remove = intel_th_pti_remove, .remove = intel_th_pti_remove,
.activate = intel_th_pti_activate, .activate = intel_th_pti_activate,
.deactivate = intel_th_pti_deactivate, .deactivate = intel_th_pti_deactivate,
.attr_group = &pti_output_group,
.driver = { .driver = {
.name = "pti", .name = "pti",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -546,8 +546,6 @@ static int stm_char_policy_set_ioctl(struct stm_file *stmf, void __user *arg) ...@@ -546,8 +546,6 @@ static int stm_char_policy_set_ioctl(struct stm_file *stmf, void __user *arg)
if (ret) if (ret)
goto err_free; goto err_free;
ret = 0;
if (stm->data->link) if (stm->data->link)
ret = stm->data->link(stm->data, stmf->output.master, ret = stm->data->link(stm->data, stmf->output.master,
stmf->output.channel); stmf->output.channel);
...@@ -668,18 +666,11 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data, ...@@ -668,18 +666,11 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data,
stm->dev.parent = parent; stm->dev.parent = parent;
stm->dev.release = stm_device_release; stm->dev.release = stm_device_release;
err = kobject_set_name(&stm->dev.kobj, "%s", stm_data->name);
if (err)
goto err_device;
err = device_add(&stm->dev);
if (err)
goto err_device;
mutex_init(&stm->link_mutex); mutex_init(&stm->link_mutex);
spin_lock_init(&stm->link_lock); spin_lock_init(&stm->link_lock);
INIT_LIST_HEAD(&stm->link_list); INIT_LIST_HEAD(&stm->link_list);
/* initialize the object before it is accessible via sysfs */
spin_lock_init(&stm->mc_lock); spin_lock_init(&stm->mc_lock);
mutex_init(&stm->policy_mutex); mutex_init(&stm->policy_mutex);
stm->sw_nmasters = nmasters; stm->sw_nmasters = nmasters;
...@@ -687,9 +678,19 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data, ...@@ -687,9 +678,19 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data,
stm->data = stm_data; stm->data = stm_data;
stm_data->stm = stm; stm_data->stm = stm;
err = kobject_set_name(&stm->dev.kobj, "%s", stm_data->name);
if (err)
goto err_device;
err = device_add(&stm->dev);
if (err)
goto err_device;
return 0; return 0;
err_device: err_device:
unregister_chrdev(stm->major, stm_data->name);
/* matches device_initialize() above */ /* matches device_initialize() above */
put_device(&stm->dev); put_device(&stm->dev);
err_free: err_free:
......
...@@ -46,9 +46,7 @@ static struct stm_data dummy_stm[DUMMY_STM_MAX]; ...@@ -46,9 +46,7 @@ static struct stm_data dummy_stm[DUMMY_STM_MAX];
static int nr_dummies = 4; static int nr_dummies = 4;
module_param(nr_dummies, int, 0600); module_param(nr_dummies, int, 0400);
static unsigned int dummy_stm_nr;
static unsigned int fail_mode; static unsigned int fail_mode;
...@@ -65,12 +63,12 @@ static int dummy_stm_link(struct stm_data *data, unsigned int master, ...@@ -65,12 +63,12 @@ static int dummy_stm_link(struct stm_data *data, unsigned int master,
static int dummy_stm_init(void) static int dummy_stm_init(void)
{ {
int i, ret = -ENOMEM, __nr_dummies = ACCESS_ONCE(nr_dummies); int i, ret = -ENOMEM;
if (__nr_dummies < 0 || __nr_dummies > DUMMY_STM_MAX) if (nr_dummies < 0 || nr_dummies > DUMMY_STM_MAX)
return -EINVAL; return -EINVAL;
for (i = 0; i < __nr_dummies; i++) { for (i = 0; i < nr_dummies; i++) {
dummy_stm[i].name = kasprintf(GFP_KERNEL, "dummy_stm.%d", i); dummy_stm[i].name = kasprintf(GFP_KERNEL, "dummy_stm.%d", i);
if (!dummy_stm[i].name) if (!dummy_stm[i].name)
goto fail_unregister; goto fail_unregister;
...@@ -86,8 +84,6 @@ static int dummy_stm_init(void) ...@@ -86,8 +84,6 @@ static int dummy_stm_init(void)
goto fail_free; goto fail_free;
} }
dummy_stm_nr = __nr_dummies;
return 0; return 0;
fail_unregister: fail_unregister:
...@@ -105,7 +101,7 @@ static void dummy_stm_exit(void) ...@@ -105,7 +101,7 @@ static void dummy_stm_exit(void)
{ {
int i; int i;
for (i = 0; i < dummy_stm_nr; i++) { for (i = 0; i < nr_dummies; i++) {
stm_unregister_device(&dummy_stm[i]); stm_unregister_device(&dummy_stm[i]);
kfree(dummy_stm[i].name); kfree(dummy_stm[i].name);
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
static int nr_devs = 4; static int nr_devs = 4;
static int interval_ms = 10; static int interval_ms = 10;
module_param(nr_devs, int, 0600); module_param(nr_devs, int, 0400);
module_param(interval_ms, int, 0600); module_param(interval_ms, int, 0600);
static struct stm_heartbeat { static struct stm_heartbeat {
...@@ -35,8 +35,6 @@ static struct stm_heartbeat { ...@@ -35,8 +35,6 @@ static struct stm_heartbeat {
unsigned int active; unsigned int active;
} stm_heartbeat[STM_HEARTBEAT_MAX]; } stm_heartbeat[STM_HEARTBEAT_MAX];
static unsigned int nr_instances;
static const char str[] = "heartbeat stm source driver is here to serve you"; static const char str[] = "heartbeat stm source driver is here to serve you";
static enum hrtimer_restart stm_heartbeat_hrtimer_handler(struct hrtimer *hr) static enum hrtimer_restart stm_heartbeat_hrtimer_handler(struct hrtimer *hr)
...@@ -74,12 +72,12 @@ static void stm_heartbeat_unlink(struct stm_source_data *data) ...@@ -74,12 +72,12 @@ static void stm_heartbeat_unlink(struct stm_source_data *data)
static int stm_heartbeat_init(void) static int stm_heartbeat_init(void)
{ {
int i, ret = -ENOMEM, __nr_instances = ACCESS_ONCE(nr_devs); int i, ret = -ENOMEM;
if (__nr_instances < 0 || __nr_instances > STM_HEARTBEAT_MAX) if (nr_devs < 0 || nr_devs > STM_HEARTBEAT_MAX)
return -EINVAL; return -EINVAL;
for (i = 0; i < __nr_instances; i++) { for (i = 0; i < nr_devs; i++) {
stm_heartbeat[i].data.name = stm_heartbeat[i].data.name =
kasprintf(GFP_KERNEL, "heartbeat.%d", i); kasprintf(GFP_KERNEL, "heartbeat.%d", i);
if (!stm_heartbeat[i].data.name) if (!stm_heartbeat[i].data.name)
...@@ -98,8 +96,6 @@ static int stm_heartbeat_init(void) ...@@ -98,8 +96,6 @@ static int stm_heartbeat_init(void)
goto fail_free; goto fail_free;
} }
nr_instances = __nr_instances;
return 0; return 0;
fail_unregister: fail_unregister:
...@@ -116,7 +112,7 @@ static void stm_heartbeat_exit(void) ...@@ -116,7 +112,7 @@ static void stm_heartbeat_exit(void)
{ {
int i; int i;
for (i = 0; i < nr_instances; i++) { for (i = 0; i < nr_devs; i++) {
stm_source_unregister_device(&stm_heartbeat[i].data); stm_source_unregister_device(&stm_heartbeat[i].data);
kfree(stm_heartbeat[i].data.name); kfree(stm_heartbeat[i].data.name);
} }
......
...@@ -107,8 +107,7 @@ stp_policy_node_masters_store(struct config_item *item, const char *page, ...@@ -107,8 +107,7 @@ stp_policy_node_masters_store(struct config_item *item, const char *page,
goto unlock; goto unlock;
/* must be within [sw_start..sw_end], which is an inclusive range */ /* must be within [sw_start..sw_end], which is an inclusive range */
if (first > INT_MAX || last > INT_MAX || first > last || if (first > last || first < stm->data->sw_start ||
first < stm->data->sw_start ||
last > stm->data->sw_end) { last > stm->data->sw_end) {
ret = -ERANGE; ret = -ERANGE;
goto unlock; goto unlock;
...@@ -342,7 +341,7 @@ stp_policies_make(struct config_group *group, const char *name) ...@@ -342,7 +341,7 @@ stp_policies_make(struct config_group *group, const char *name)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
*p++ = '\0'; *p = '\0';
stm = stm_find_device(devname); stm = stm_find_device(devname);
kfree(devname); kfree(devname);
......
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