From: Hans Verkuil <hverkuil@xs4all.nl>
To: Andrey Utkin <andrey.utkin@corp.bluecherry.net>,
Linux Media <linux-media@vger.kernel.org>,
"kernel-mentors@selenic.com" <kernel-mentors@selenic.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: "hans.verkuil" <hans.verkuil@cisco.com>, khalasa <khalasa@piap.pl>
Subject: Re: On register r/w macros/procedures of drivers/media/pci
Date: Sun, 19 Apr 2015 10:28:09 +0200 [thread overview]
Message-ID: <55336719.5000301@xs4all.nl> (raw)
In-Reply-To: <CAM_ZknVRzewY23-ZGJrZxEmLa2k6DXyxb1pH-1dJ9tLV7VZ03w@mail.gmail.com>
On 04/19/2015 09:36 AM, Andrey Utkin wrote:
> I am starting a work on driver for techwell tw5864 media grabber&encoder.
> I am basing on tw68 driver (mentorship, advising and testing by board
> owners are appreciated). And here (and in some other
> drivers/media/pci/ drivers) I see what confuses me:
>
> tw68-core.c:
> dev->lmmio = ioremap(pci_resource_start(pci_dev, 0),
> pci_resource_len(pci_dev, 0));
> dev->bmmio = (__u8 __iomem *)dev->lmmio;
>
> tw68.h:
> #define tw_readl(reg) readl(dev->lmmio + ((reg) >> 2))
> #define tw_readb(reg) readb(dev->bmmio + (reg))
> #define tw_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2))
> #define tw_writeb(reg, value) writeb((value), dev->bmmio + (reg))
>
> I am mostly userland developer and I wouldn't expect bmmio pointer to
> contain value numerically different from lmmio after such simple
> casting.
Check the types of llmio and bbmio:
u32 __iomem *lmmio;
u8 __iomem *bmmio;
So the values of the pointers are the same, but the types are not.
So 'lmmio + 1' == 'bmmio + sizeof(u32)' == 'bbmio + 4'.
Since all the registers are defined as byte offsets relative to the start
of the memory map you cannot just do 'lmmio + reg' since that would be a
factor 4 off. Instead you have to divide by 4 to get it back in line.
Frankly, I don't think lmmio is necessary at all since readl/writel don't
need a u32 pointer at all since they use void pointers. I never noticed
that when I cleaned up the tw68 driver. Using 'void __iomem *mmio' instead
of lmmio/bmmio and dropping the shifts in the tw_ macros would work just
as well.
> But still, if this is correct, then how should I implement
> tw_{read,write}w to operate on 2 bytes (a word)? Similarly, it would
> look like this:
> #define tw_readl(reg) readl(dev->lmmio + ((reg) >> 1))
As suggested above, just use a single void __iomem *mmio pointer.
> That looks odd.
>
> In contrary, in drivers/media/pci/dm1105, we see no explicit shifting
> of register address. It uses {in,out}{b,w,l} macros, which seem to
> turn out the same {read,write}{b,w,l} (with some reservations):
> http://lxr.free-electrons.com/source/include/asm-generic/io.h#L354
>
> dm1105.c:#define dm_io_mem(reg) ((unsigned long)(&dev->io_mem[reg]))
> dm1105.c:#define dm_readb(reg) inb(dm_io_mem(reg))
> dm1105.c:#define dm_writeb(reg, value) outb((value), (dm_io_mem(reg)))
> dm1105.c:#define dm_readw(reg) inw(dm_io_mem(reg))
> dm1105.c:#define dm_writew(reg, value) outw((value), (dm_io_mem(reg)))
> dm1105.c:#define dm_readl(reg) inl(dm_io_mem(reg))
> dm1105.c:#define dm_writel(reg, value) outl((value), (dm_io_mem(reg)))
>
> This looks like contradiction to me (shifting register address vs. no
> shifting), so that one practice may be even just wrong and broken
> (which is hard to believe due to active maintenance of all drivers).
> I highly appreciate your help me in determining the best practice to
> follow in this new driver.
> Thanks.
>
Hope this helps,
Hans
next prev parent reply other threads:[~2015-04-19 8:28 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-19 7:36 On register r/w macros/procedures of drivers/media/pci Andrey Utkin
2015-04-19 8:28 ` Hans Verkuil [this message]
2015-04-19 8:55 ` Andrey Utkin
2015-04-20 11:18 ` Krzysztof Hałasa
2015-04-20 11:20 ` Andrey Utkin
2015-04-20 12:45 ` Krzysztof Hałasa
2015-04-20 13:00 ` Andrey Utkin
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=55336719.5000301@xs4all.nl \
--to=hverkuil@xs4all.nl \
--cc=andrey.utkin@corp.bluecherry.net \
--cc=hans.verkuil@cisco.com \
--cc=kernel-mentors@selenic.com \
--cc=khalasa@piap.pl \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.