staging: fsl-mc: dpmcp opening/closing refactoring

Before, we were opening and closing a mc_io's dpmcp object
in fsl_mc_portal_reset(), since that was the only function that was
calling dpmcp MC operations. However, it is better for maintainability
to open the dpmcp object when it gets associated with an mc_io object,
and close it when this association is terminated. This way, we are free
to call dpmcp operations on a mc_io's dpmcp object at any time, without
having to check if the dpmcp object is opened or not.

Consequently, the creation/teardown of the association between
an mc_io object and a dpmcp is now encapsulated in two functions:
fsl_mc_io_set_dpmcp()/fsl_mc_io_unset_dpmcp(). Besides, setting
the corresponding pointers for the association, these functions
open and close the dpmcp object respectively.

Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
J. German Rivera 2015-10-17 11:18:15 -05:00 committed by Greg Kroah-Hartman
parent ffcd52ef09
commit d2f8499153
3 changed files with 73 additions and 21 deletions

View File

@ -373,30 +373,17 @@ EXPORT_SYMBOL_GPL(fsl_mc_portal_free);
int fsl_mc_portal_reset(struct fsl_mc_io *mc_io) int fsl_mc_portal_reset(struct fsl_mc_io *mc_io)
{ {
int error; int error;
u16 token;
struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
if (WARN_ON(!dpmcp_dev)) if (WARN_ON(!dpmcp_dev))
return -EINVAL; return -EINVAL;
error = dpmcp_open(mc_io, 0, dpmcp_dev->obj_desc.id, &token); error = dpmcp_reset(mc_io, 0, dpmcp_dev->mc_handle);
if (error < 0) {
dev_err(&dpmcp_dev->dev, "dpmcp_open() failed: %d\n", error);
return error;
}
error = dpmcp_reset(mc_io, 0, token);
if (error < 0) { if (error < 0) {
dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error); dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error);
return error; return error;
} }
error = dpmcp_close(mc_io, 0, token);
if (error < 0) {
dev_err(&dpmcp_dev->dev, "dpmcp_close() failed: %d\n", error);
return error;
}
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(fsl_mc_portal_reset); EXPORT_SYMBOL_GPL(fsl_mc_portal_reset);

View File

@ -75,6 +75,7 @@ int __must_check fsl_create_mc_io(struct device *dev,
struct fsl_mc_device *dpmcp_dev, struct fsl_mc_device *dpmcp_dev,
u32 flags, struct fsl_mc_io **new_mc_io) u32 flags, struct fsl_mc_io **new_mc_io)
{ {
int error;
struct fsl_mc_io *mc_io; struct fsl_mc_io *mc_io;
void __iomem *mc_portal_virt_addr; void __iomem *mc_portal_virt_addr;
struct resource *res; struct resource *res;
@ -87,8 +88,6 @@ int __must_check fsl_create_mc_io(struct device *dev,
mc_io->flags = flags; mc_io->flags = flags;
mc_io->portal_phys_addr = mc_portal_phys_addr; mc_io->portal_phys_addr = mc_portal_phys_addr;
mc_io->portal_size = mc_portal_size; mc_io->portal_size = mc_portal_size;
mc_io->dpmcp_dev = dpmcp_dev;
dpmcp_dev->mc_io = mc_io;
res = devm_request_mem_region(dev, res = devm_request_mem_region(dev,
mc_portal_phys_addr, mc_portal_phys_addr,
mc_portal_size, mc_portal_size,
@ -111,8 +110,18 @@ int __must_check fsl_create_mc_io(struct device *dev,
} }
mc_io->portal_virt_addr = mc_portal_virt_addr; mc_io->portal_virt_addr = mc_portal_virt_addr;
if (dpmcp_dev) {
error = fsl_mc_io_set_dpmcp(mc_io, dpmcp_dev);
if (error < 0)
goto error_destroy_mc_io;
}
*new_mc_io = mc_io; *new_mc_io = mc_io;
return 0; return 0;
error_destroy_mc_io:
fsl_destroy_mc_io(mc_io);
return error;
} }
EXPORT_SYMBOL_GPL(fsl_create_mc_io); EXPORT_SYMBOL_GPL(fsl_create_mc_io);
@ -123,21 +132,72 @@ EXPORT_SYMBOL_GPL(fsl_create_mc_io);
*/ */
void fsl_destroy_mc_io(struct fsl_mc_io *mc_io) void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
{ {
struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
if (dpmcp_dev)
fsl_mc_io_unset_dpmcp(mc_io);
devm_iounmap(mc_io->dev, mc_io->portal_virt_addr); devm_iounmap(mc_io->dev, mc_io->portal_virt_addr);
devm_release_mem_region(mc_io->dev, devm_release_mem_region(mc_io->dev,
mc_io->portal_phys_addr, mc_io->portal_phys_addr,
mc_io->portal_size); mc_io->portal_size);
mc_io->portal_virt_addr = NULL; mc_io->portal_virt_addr = NULL;
if (mc_io->dpmcp_dev) {
WARN_ON(mc_io->dpmcp_dev->mc_io != mc_io);
mc_io->dpmcp_dev->mc_io = NULL;
}
devm_kfree(mc_io->dev, mc_io); devm_kfree(mc_io->dev, mc_io);
} }
EXPORT_SYMBOL_GPL(fsl_destroy_mc_io); EXPORT_SYMBOL_GPL(fsl_destroy_mc_io);
int fsl_mc_io_set_dpmcp(struct fsl_mc_io *mc_io,
struct fsl_mc_device *dpmcp_dev)
{
int error;
if (WARN_ON(!dpmcp_dev))
return -EINVAL;
if (WARN_ON(mc_io->dpmcp_dev))
return -EINVAL;
if (WARN_ON(dpmcp_dev->mc_io))
return -EINVAL;
error = dpmcp_open(mc_io,
0,
dpmcp_dev->obj_desc.id,
&dpmcp_dev->mc_handle);
if (error < 0)
return error;
mc_io->dpmcp_dev = dpmcp_dev;
dpmcp_dev->mc_io = mc_io;
return 0;
}
EXPORT_SYMBOL_GPL(fsl_mc_io_set_dpmcp);
void fsl_mc_io_unset_dpmcp(struct fsl_mc_io *mc_io)
{
int error;
struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
if (WARN_ON(!dpmcp_dev))
return;
if (WARN_ON(dpmcp_dev->mc_io != mc_io))
return;
error = dpmcp_close(mc_io,
0,
dpmcp_dev->mc_handle);
if (error < 0) {
dev_err(&dpmcp_dev->dev, "dpmcp_close() failed: %d\n",
error);
}
mc_io->dpmcp_dev = NULL;
dpmcp_dev->mc_io = NULL;
}
EXPORT_SYMBOL_GPL(fsl_mc_io_unset_dpmcp);
static int mc_status_to_error(enum mc_cmd_status status) static int mc_status_to_error(enum mc_cmd_status status)
{ {
static const int mc_status_to_error_map[] = { static const int mc_status_to_error_map[] = {

View File

@ -69,6 +69,11 @@ int __must_check fsl_create_mc_io(struct device *dev,
void fsl_destroy_mc_io(struct fsl_mc_io *mc_io); void fsl_destroy_mc_io(struct fsl_mc_io *mc_io);
int fsl_mc_io_set_dpmcp(struct fsl_mc_io *mc_io,
struct fsl_mc_device *dpmcp_dev);
void fsl_mc_io_unset_dpmcp(struct fsl_mc_io *mc_io);
int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd); int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
#endif /* _FSL_MC_SYS_H */ #endif /* _FSL_MC_SYS_H */