From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Marek Vasut <marex@denx.de>
Cc: linux-input@vger.kernel.org, ch@denx.de,
Joe Hung <joe_hung@ilitek.com>, Luca Hsu <luca_hsu@ilitek.com>
Subject: Re: [PATCH v2 3/3] Input: ili210x - add ili251x firmware update support
Date: Mon, 30 Aug 2021 19:05:08 -0700 [thread overview]
Message-ID: <YS2OVMBQ0paMpJvh@google.com> (raw)
In-Reply-To: <3233bfac-6d9d-da86-c4f9-18a9eab326d4@denx.de>
On Tue, Aug 31, 2021 at 01:27:21AM +0200, Marek Vasut wrote:
> On 8/30/21 11:14 PM, Dmitry Torokhov wrote:
>
> [...]
>
> > > + if (ret) {
> > > + dev_err(dev, "Failed to request firmware %s, ret=%d\n", fwname, ret);
> > > + return ret;
> > > + }
> > > +
> > > + /*
> > > + * The firmware ihex blob can never be bigger than 64 kiB, so make this
> > > + * simple -- allocate a 64 kiB buffer, iterate over the ihex blob records
> > > + * once, copy them all into this buffer at the right locations, and then
> > > + * do all operations on this linear buffer.
> > > + */
> > > + fw_buf = kcalloc(1, SZ_64K, GFP_KERNEL);
> >
> > Why kcalloc and not kzalloc?
>
> Because the firmware blob might be sparse (with gaps in it) and those gaps
> should be zeroed out instead of random data (see your question about the 32
> byte long memcpy() below (*) as well).
That is the exact purpose of kZalloc - to ZERO-out allocation (as
compared to kmalloc() which leaves memory uninitialized).
>
> > > + if (!fw_buf) {
> > > + ret = -ENOMEM;
> > > + goto err_alloc;
> > > + }
> > > +
> > > + rec = (const struct ihex_binrec *)fw->data;
> > > + while (rec) {
> > > + fw_addr = be32_to_cpu(rec->addr);
> > > + fw_len = be16_to_cpu(rec->len);
> > > +
> > > + if (fw_addr + fw_len > SZ_64K) {
> > > + ret = -EFBIG;
> > > + goto err_big;
> > > + }
> > > +
> > > + /* Find the last address before DF start address, that is AC end */
> > > + if (fw_addr == 0xf000)
> > > + *ac_end = fw_last_addr;
> > > + fw_last_addr = fw_addr + fw_len;
> > > +
> > > + memcpy(fw_buf + fw_addr, rec->data, fw_len);
> > > + rec = ihex_next_binrec(rec);
> > > + }
>
> [...]
>
> > > +static int ili251x_firmware_busy(struct i2c_client *client)
> > > +{
> > > + struct ili210x *priv = i2c_get_clientdata(client);
> > > + int ret, i = 0;
> > > + u8 data;
> > > +
> > > + do {
> > > + /* The read_reg already contains suitable delay */
> > > + ret = priv->chip->read_reg(client, 0x80, &data, 1);
> >
> > Can we have symbolic name for this register (and others).
>
> The name of this one isn't part of the example code, so ... I can call it
> something, but who knows what it really is.
>
> I believe I did manage to find what the other registers are called already.
OK.
>
> [...]
>
> > > + ret = ili251x_firmware_busy(client);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + for (fw_addr = start; fw_addr < end; fw_addr += 32) {
> > > + fw_data[0] = REG_WRITE_DATA;
> > > + memcpy(&(fw_data[1]), fwbuf + fw_addr, 32);
> >
> > Is it guaranteed that we have enough data (32 bytes) and we will not
> > reach past the buffer?
>
> Yes, see above (*). If the firmware blob entry were too short, this would
> pull in zeroes.
>
> I tried iterating through the firmware file, but using linear buffer for the
> firmware results in far less convoluted code, and considering it is not
> performance critical, I think this is ok.
Could you drop a comment to that effect.
>
> [...]
>
> > > +static ssize_t ili210x_firmware_update_store(struct device *dev,
> > > + struct device_attribute *attr,
> > > + const char *buf, size_t count)
> > > +{
> > > + struct i2c_client *client = to_i2c_client(dev);
> > > + struct ili210x *priv = i2c_get_clientdata(client);
> > > + char fwname[NAME_MAX];
> > > + u16 ac_end, df_end;
> > > + u8 *fwbuf;
> > > + int ret;
> > > + int i;
> > > +
> > > + if (count >= NAME_MAX) {
> > > + dev_err(dev, "File name too long\n");
> > > + return -EINVAL;
> > > + }
> > > +
> > > + memcpy(fwname, buf, count);
> > > + if (fwname[count - 1] == '\n')
> > > + fwname[count - 1] = '\0';
> > > + else
> > > + fwname[count] = '\0';
> >
> > I believe the practice is to use constant firmware name based on driver
> > or chip name. If there is desire to allow dynamic firmware name for
> > given device I think it should be handled at firmware loader core.
>
> There are a couple of input devices which do similar thing, see e.g.:
> drivers/input/mouse/cyapa.c
> drivers/input/rmi4/rmi_f34.c
>
> The ilitek firmware contains both firmware and calibration data, so you
> might end up with a usecase where you switch between different firmware
> blobs at runtime.
>
> That's why it is implemented this way.
Right, and I'd rather not proliferate this any further. Can you drop the
filename support from this patch so it can be merged easily, and then we
can continue discussion on this topic separately?
Thanks.
--
Dmitry
next prev parent reply other threads:[~2021-08-31 2:05 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-27 21:12 [PATCH v2 1/3] Input: ili210x - use resolution from ili251x firmware Marek Vasut
2021-08-27 21:12 ` [PATCH v2 2/3] Input: ili210x - export ili251x version details via sysfs Marek Vasut
2021-08-30 21:01 ` Dmitry Torokhov
2021-08-30 23:02 ` Marek Vasut
2021-08-30 23:20 ` Dmitry Torokhov
2021-08-30 23:33 ` Marek Vasut
2021-08-30 23:45 ` Dmitry Torokhov
2021-08-27 21:12 ` [PATCH v2 3/3] Input: ili210x - add ili251x firmware update support Marek Vasut
2021-08-30 21:14 ` Dmitry Torokhov
2021-08-30 23:27 ` Marek Vasut
2021-08-31 2:05 ` Dmitry Torokhov [this message]
2021-08-30 20:55 ` [PATCH v2 1/3] Input: ili210x - use resolution from ili251x firmware Dmitry Torokhov
2021-08-30 22:49 ` Marek Vasut
2021-08-30 23:21 ` Dmitry Torokhov
2021-08-30 23:31 ` Marek Vasut
2021-08-30 23:46 ` Dmitry Torokhov
2021-08-31 0:01 ` Marek Vasut
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=YS2OVMBQ0paMpJvh@google.com \
--to=dmitry.torokhov@gmail.com \
--cc=ch@denx.de \
--cc=joe_hung@ilitek.com \
--cc=linux-input@vger.kernel.org \
--cc=luca_hsu@ilitek.com \
--cc=marex@denx.de \
/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;
as well as URLs for NNTP newsgroup(s).