mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kim Phillips <kim.phillips@freescale.com>
To: "J. German Rivera" <German.Rivera@freescale.com>
Cc: <gregkh@linuxfoundation.org>, <arnd@arndb.de>,
	<linux-kernel@vger.kernel.org>, <stuart.yoder@freescale.com>,
	<Kim.Phillips@freescale.com>, <scottwood@freescale.com>,
	<agraf@suse.de>, <linuxppc-release@linux.freescale.net>
Subject: Re: [PATCH 1/3 v2] drivers/bus: Added Freescale Management Complex APIs
Date: Tue, 23 Sep 2014 19:49:01 -0500	[thread overview]
Message-ID: <20140923194901.894483bfaef97d13d12c75a5@freescale.com> (raw)
In-Reply-To: <1411166981-3610-2-git-send-email-German.Rivera@freescale.com>

On Fri, 19 Sep 2014 17:49:39 -0500
"J. German Rivera" <German.Rivera@freescale.com> wrote:

> +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
...
> +	err = mc_send_command(mc_io, &cmd);
> +	if (err)
> +		return err;
> +
> +		DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);

alignment

> +int dpmng_load_aiop(struct fsl_mc_io *mc_io,
> +		    int aiop_tile_id, uint8_t *img_addr, int img_size)
> +{
> +	struct mc_command cmd = { 0 };
> +	uint64_t img_paddr = virt_to_phys(img_addr);

Direct use of virt_to_phys by drivers is deprecated; this code needs
to map the i/o space via the DMA API.  This is in order to handle
situations where e.g., the device sitting behind an IOMMU.  See
Documentation/DMA-API* for more info.

> +/**
> + * Delay in microseconds between polling iterations while
> + * waiting for MC command completion
> + */
> +#define MC_CMD_COMPLETION_POLLING_INTERVAL_USECS    500	/* 0.5 ms */
> +
> +int __must_check fsl_create_mc_io(struct device *dev,
> +				  phys_addr_t mc_portal_phys_addr,
> +				  uint32_t mc_portal_size,
> +				  uint32_t flags, struct fsl_mc_io **new_mc_io)
> +{
> +	struct fsl_mc_io *mc_io;
> +	void __iomem *mc_portal_virt_addr;
> +	struct resource *res;
> +
> +	mc_io = devm_kzalloc(dev, sizeof(*mc_io), GFP_KERNEL);
> +	if (mc_io == NULL)
> +		return -ENOMEM;
> +
> +	mc_io->dev = dev;
> +	mc_io->flags = flags;
> +	mc_io->portal_phys_addr = mc_portal_phys_addr;
> +	mc_io->portal_size = mc_portal_size;
> +	if (mc_io->flags & FSL_MC_PORTAL_SHARED_BY_INT_HANDLERS)
> +		spin_lock_init(&mc_io->spinlock);

I'm confused - this patseries doesn't register an interrupt handler,
so this can't be true (or it's premature if it will, in which case
it should be left out for now).

However, if somehow users of this code register an IRQ handler for
the portal (I don't see any users to tell how they get the IRQ line
either?), then it's up to them to establish mutual exclusion rules
for access, among themselves.  Unless you think they will be calling
mc_send_command from h/w IRQ context, in which case I'd reconsider
that assumption because send_command looks like it'd take too long
to get an answer from the h/w - IRQ handlers should just ack the h/w
IRQ, and notify the scheduler that the driver has work to do (in s/w
IRQ context perhaps).

> +	else if (mc_io->flags & FSL_MC_PORTAL_SHARED_BY_THREADS)
> +		mutex_init(&mc_io->mutex);

I'd assume SHARED_BY_THREADS to always be true in linux.

> +	res = devm_request_mem_region(dev,
> +				      mc_portal_phys_addr,
> +				      mc_portal_size,
> +				      "mc_portal");
> +	if (res == NULL) {
> +		dev_err(dev,
> +			"devm_request_mem_region failed for MC portal %#llx\n",
> +			mc_portal_phys_addr);
> +		return -EBUSY;
> +	}
> +
> +	mc_portal_virt_addr = devm_ioremap_nocache(dev,
> +						   mc_portal_phys_addr,
> +						   mc_portal_size);
> +	if (mc_portal_virt_addr == NULL) {
> +		dev_err(dev,
> +			"devm_ioremap_nocache failed for MC portal %#llx\n",
> +			mc_portal_phys_addr);
> +		return -ENXIO;
> +	}
> +
> +	mc_io->portal_virt_addr = mc_portal_virt_addr;
> +	*new_mc_io = mc_io;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(fsl_create_mc_io);
> +
> +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
> +{
> +	if (WARN_ON(mc_io->portal_virt_addr == NULL))
> +		return;

this is unnecessary - you'll get the stack trace anyway, and users
calling destroy on a not successfully created mc_io object should
not get the luxury of maybe being able to continue after the stack
trace, after possibly leaking memory.

> +	mc_io->portal_virt_addr = NULL;
> +	devm_kfree(mc_io->dev, mc_io);

like I said before, there's really no point in clearing something
out right before it's freed.

> +}
> +EXPORT_SYMBOL_GPL(fsl_destroy_mc_io);
> +
> +static int mc_status_to_error(enum mc_cmd_status status)
> +{
> +	static const int mc_status_to_error_map[] = {
> +		[MC_CMD_STATUS_OK] = 0,
> +		[MC_CMD_STATUS_AUTH_ERR] = -EACCES,
> +		[MC_CMD_STATUS_NO_PRIVILEGE] = -EPERM,
> +		[MC_CMD_STATUS_DMA_ERR] = -EIO,
> +		[MC_CMD_STATUS_CONFIG_ERR] = -ENXIO,
> +		[MC_CMD_STATUS_TIMEOUT] = -ETIMEDOUT,
> +		[MC_CMD_STATUS_NO_RESOURCE] = -ENAVAIL,
> +		[MC_CMD_STATUS_NO_MEMORY] = -ENOMEM,
> +		[MC_CMD_STATUS_BUSY] = -EBUSY,
> +		[MC_CMD_STATUS_UNSUPPORTED_OP] = -ENOTSUPP,
> +		[MC_CMD_STATUS_INVALID_STATE] = -ENODEV,
> +	};
> +
> +	if (WARN_ON(status >= ARRAY_SIZE(mc_status_to_error_map)))
> +		return -EINVAL;
> +	return mc_status_to_error_map[status];
> +}

great - CONFIG_ERR is now -ENXIO instead of -EINVAL, so at least
it's now mutually exclusive, but it doesn't handle
MC_CMD_STATUS_READY - should it?

> +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd)
> +{
> +	enum mc_cmd_status status;
> +	int error;
> +	unsigned long irqsave_flags = 0;
> +	unsigned long jiffies_until_timeout =
> +	    jiffies + MC_CMD_COMPLETION_TIMEOUT_JIFFIES;
> +
> +	/*
> +	 * Acquire lock depending on mc_io flags:
> +	 */
> +	if (mc_io->flags & FSL_MC_PORTAL_SHARED_BY_INT_HANDLERS) {
> +		if (mc_io->flags & FSL_MC_PORTAL_SHARED_BY_THREADS)
> +			spin_lock_irqsave(&mc_io->spinlock, irqsave_flags);
> +		else
> +			spin_lock(&mc_io->spinlock);
> +	} else if (mc_io->flags & FSL_MC_PORTAL_SHARED_BY_THREADS) {
> +		mutex_lock(&mc_io->mutex);
> +	}

again, I think we need to drop the coming from h/w IRQ context here
(SHARED_BY_INT_HANDLERS); there's no IRQ handlers in this
patchseries, and calling this function from an IRQ handler would be
prohibitively wasteful, guessing by the udelay and timeout values
below.

Can we just mutex_lock for now, and unconditionally (no
SHARED_BY_THREADS check), to protect from nesting?

> +	/*
> +	 * Wait for response from the MC hardware:
> +	 */
> +	for (;;) {
> +		status = mc_read_response(mc_io->portal_virt_addr, cmd);
> +		if (status != MC_CMD_STATUS_READY)
> +			break;
> +
> +		/*
> +		 * TODO: When MC command completion interrupts are supported
> +		 * call wait function here instead of udelay()
> +		 */
> +		udelay(MC_CMD_COMPLETION_POLLING_INTERVAL_USECS);

this pauses any caller for 0.5ms on every successful command
write.  Can the next submission of the patchseries wait until
completion IRQs are indeed supported, since both that and the above
locking needs to be resolved?

Kim

  reply	other threads:[~2014-09-24  0:54 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-19 22:49 [PATCH 0/3 v2] drivers/bus: Freescale Management Complex bus driver patch series J. German Rivera
2014-09-19 22:49 ` [PATCH 1/3 v2] drivers/bus: Added Freescale Management Complex APIs J. German Rivera
2014-09-24  0:49   ` Kim Phillips [this message]
2014-09-25  2:23     ` German Rivera
2014-09-25  3:40       ` Kim Phillips
2014-09-25 15:44         ` German Rivera
2014-09-25 16:16           ` Scott Wood
2014-09-25 16:44             ` German Rivera
2014-09-25 20:05               ` Scott Wood
2014-09-19 22:49 ` [PATCH 2/3 v2] drivers/bus: Freescale Management Complex (fsl-mc) bus driver J. German Rivera
2014-09-19 22:49 ` [PATCH 3/3 v2] drivers/bus: Device driver for FSL-MC DPRC devices J. German Rivera
2014-10-01  2:19   ` Timur Tabi
2014-10-01  2:27     ` Scott Wood
2014-10-01  2:35       ` Timur Tabi
2014-10-02 16:36     ` German Rivera
2014-10-02 17:19       ` Timur Tabi
2014-09-22 16:53 ` [PATCH 0/3 v2] drivers/bus: Freescale Management Complex bus driver patch series Kim Phillips
2014-09-22 17:59   ` Stuart Yoder
2014-09-22 22:03     ` Kim Phillips
2014-09-23 14:52     ` German Rivera

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140923194901.894483bfaef97d13d12c75a5@freescale.com \
    --to=kim.phillips@freescale.com \
    --cc=German.Rivera@freescale.com \
    --cc=agraf@suse.de \
    --cc=arnd@arndb.de \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-release@linux.freescale.net \
    --cc=scottwood@freescale.com \
    --cc=stuart.yoder@freescale.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®