public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
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

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox