From: Paul Burton <paul.burton@imgtec.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 4/9] ns16550: Support I/O accessors selected by DT
Date: Fri, 29 Jan 2016 16:09:37 +0000 [thread overview]
Message-ID: <20160129160937.GC3017@NP-P-BURTON> (raw)
In-Reply-To: <CAPnjgZ0LPhot4e1oAUP81PVesbn15QuwBA7Fp658k3zxAHcyng@mail.gmail.com>
On Fri, Jan 29, 2016 at 07:56:19AM -0700, Simon Glass wrote:
> Hi Paul,
>
> On 29 January 2016 at 06:54, Paul Burton <paul.burton@imgtec.com> wrote:
> > Support making use of I/O accessors for ports when a device tree
> > specified an I/O resource. This allows for systems where we have a mix
> > of ns16550 ports, some of which should be accessed via I/O ports & some
> > of which should be accessed via readb/writeb.
> >
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > ---
> >
> > drivers/serial/ns16550.c | 46 ++++++++++++++++++++++++++++++++++++++--------
> > include/ns16550.h | 31 ++++++++++++++++++-------------
> > 2 files changed, 56 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
> > index 93dad33..b1d5319 100644
> > --- a/drivers/serial/ns16550.c
> > +++ b/drivers/serial/ns16550.c
> > @@ -11,6 +11,7 @@
> > #include <ns16550.h>
> > #include <serial.h>
> > #include <watchdog.h>
> > +#include <linux/ioport.h>
> > #include <linux/types.h>
> > #include <asm/io.h>
> >
> > @@ -102,7 +103,7 @@ static void ns16550_writeb(NS16550_t port, int offset, int value)
> > offset *= 1 << plat->reg_shift;
> > addr = map_physmem(plat->base, 0, MAP_NOCACHE) + offset;
> > /*
> > - * As far as we know it doesn't make sense to support selection of
> > + * For many platforms it doesn't make sense to support selection of
> > * these options at run-time, so use the existing CONFIG options.
> > */
> > serial_out_shift(addr, plat->reg_shift, value);
> > @@ -119,13 +120,33 @@ static int ns16550_readb(NS16550_t port, int offset)
> > return serial_in_shift(addr, plat->reg_shift);
> > }
> >
> > +static void ns16550_outb(NS16550_t port, int offset, int value)
> > +{
> > + struct ns16550_platdata *plat = port->plat;
> > +
> > + offset *= 1 << plat->reg_shift;
> > + outb(value, plat->base + offset);
> > +}
> > +
> > +static int ns16550_inb(NS16550_t port, int offset)
> > +{
> > + struct ns16550_platdata *plat = port->plat;
> > +
> > + offset *= 1 << plat->reg_shift;
> > + return inb(plat->base + offset);
> > +}
> > +
> > /* We can clean these up once everything is moved to driver model */
> > -#define serial_out(value, addr) \
> > - ns16550_writeb(com_port, \
> > - (unsigned char *)addr - (unsigned char *)com_port, value)
> > -#define serial_in(addr) \
> > - ns16550_readb(com_port, \
> > - (unsigned char *)addr - (unsigned char *)com_port)
> > +#define serial_out(value, addr) do { \
> > + int offset = (unsigned char *)addr - (unsigned char *)com_port; \
> > + com_port->plat->out(com_port, offset, value); \
>
> I really don't want to introduce function pointers here. This driver
> is a mess but my hope was that when we remove the non-driver-model
> code we can clean it up.
>
> I suggest storing the access method in com_port->plat and then using
> if() or switch() to select the right one. We can always add #ifdefs to
> keep the code size down if it becomes a problem.
Hi Simon,
I originally had a field in the platform data & an if statement, but
switched to this because it seemed neater & avoids checks on every read
or write.
I can put it back if you insist, but whilst I agree that the driver
needs some cleanup I'm not sure this would qualify.
> > +} while (0)
> > +
> > +#define serial_in(addr) ({ \
> > + int offset = (unsigned char *)addr - (unsigned char *)com_port; \
> > + int value = com_port->plat->in(com_port, offset); \
> > + value; \
> > +})
> > #endif
> >
> > static inline int calc_divisor(NS16550_t port, int clock, int baudrate)
> > @@ -365,9 +386,10 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
> > {
> > struct ns16550_platdata *plat = dev->platdata;
> > fdt_addr_t addr;
> > + unsigned int flags;
> >
> > /* try Processor Local Bus device first */
> > - addr = dev_get_addr(dev);
> > + addr = dev_get_addr_flags(dev, &flags);
> > #if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI)
> > if (addr == FDT_ADDR_T_NONE) {
> > /* then try pci device */
> > @@ -400,6 +422,14 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
> > if (addr == FDT_ADDR_T_NONE)
> > return -EINVAL;
> >
> > + if (flags & IORESOURCE_IO) {
> > + plat->in = ns16550_inb;
> > + plat->out = ns16550_outb;
> > + } else {
> > + plat->in = ns16550_readb;
> > + plat->out = ns16550_writeb;
> > + }
> > +
> > plat->base = addr;
> > plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
> > "reg-shift", 0);
> > diff --git a/include/ns16550.h b/include/ns16550.h
> > index 4e62067..097f64b 100644
> > --- a/include/ns16550.h
> > +++ b/include/ns16550.h
> > @@ -45,19 +45,6 @@
> > unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
> > #endif
> >
> > -/**
> > - * struct ns16550_platdata - information about a NS16550 port
> > - *
> > - * @base: Base register address
> > - * @reg_shift: Shift size of registers (0=byte, 1=16bit, 2=32bit...)
> > - * @clock: UART base clock speed in Hz
> > - */
> > -struct ns16550_platdata {
> > - unsigned long base;
> > - int reg_shift;
> > - int clock;
> > -};
> > -
> > struct udevice;
> >
> > struct NS16550 {
> > @@ -100,6 +87,24 @@ struct NS16550 {
> >
> > typedef struct NS16550 *NS16550_t;
> >
> > +/**
> > + * struct ns16550_platdata - information about a NS16550 port
> > + *
> > + * @base: Base register address
> > + * @reg_shift: Shift size of registers (0=byte, 1=16bit, 2=32bit...)
> > + * @clock: UART base clock speed in Hz
> > + * @is_io: Use I/O, not memory, accessors
> > + */
> > +struct ns16550_platdata {
> > + unsigned long base;
> > + int reg_shift;
> > + int clock;
> > +#ifdef CONFIG_DM_SERIAL
> > + int (*in)(NS16550_t port, int offset);
> > + void (*out)(NS16550_t port, int offset, int value);
> > +#endif
> > +};
>
> Does the above need to move? It would reduce the diff if you left it
> in the same place.
It needs the declaration of NS16550_t. A forward declaration would do I
suppose, but it seemed neater to not need it.
Thanks,
Paul
> > +
> > /*
> > * These are the definitions for the FIFO Control Register
> > */
> > --
> > 2.7.0
> >
>
> Regards,
> Simon
next prev parent reply other threads:[~2016-01-29 16:09 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-29 13:54 [U-Boot] [PATCH 0/9] Malta UART using device model & device tree Paul Burton
2016-01-29 13:54 ` [U-Boot] [PATCH 1/9] ioport.h: Remove struct resource & co Paul Burton
2016-01-29 14:06 ` Marek Vasut
2016-01-29 15:58 ` Paul Burton
2016-01-29 20:50 ` Marek Vasut
2016-01-29 13:54 ` [U-Boot] [PATCH 2/9] fdt: Support for ISA busses Paul Burton
2016-01-29 14:56 ` Simon Glass
2016-01-29 16:04 ` Paul Burton
2016-01-29 18:23 ` Simon Glass
2016-01-29 13:54 ` [U-Boot] [PATCH 3/9] fdt: Support providing IORESOURCE_* flags from translation Paul Burton
2016-01-29 14:56 ` Simon Glass
2016-01-29 13:54 ` [U-Boot] [PATCH 4/9] ns16550: Support I/O accessors selected by DT Paul Burton
2016-01-29 14:56 ` Simon Glass
2016-01-29 16:09 ` Paul Burton [this message]
2016-01-29 18:23 ` Simon Glass
2016-01-29 13:54 ` [U-Boot] [PATCH 5/9] MIPS: Remove SLOW_DOWN_IO Paul Burton
2016-02-01 21:27 ` Daniel Schwierzeck
2016-01-29 13:54 ` [U-Boot] [PATCH 6/9] MIPS: Support dynamic I/O port base address Paul Burton
2016-02-01 21:27 ` Daniel Schwierzeck
2016-01-29 13:54 ` [U-Boot] [PATCH 7/9] malta: Set I/O port base early Paul Burton
2016-02-01 21:24 ` Daniel Schwierzeck
2016-01-29 13:54 ` [U-Boot] [PATCH 8/9] malta: Use I/O accessors for SuperI/O controller Paul Burton
2016-02-01 21:26 ` Daniel Schwierzeck
2016-01-29 13:54 ` [U-Boot] [PATCH 9/9] malta: Use device model & tree for UART Paul Burton
2016-01-29 14:05 ` [U-Boot] [PATCH 0/9] Malta UART using device model & device tree Marek Vasut
2016-01-29 14:50 ` Daniel Schwierzeck
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=20160129160937.GC3017@NP-P-BURTON \
--to=paul.burton@imgtec.com \
--cc=u-boot@lists.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 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.