From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QpE8V-0000jT-J8 for barebox@lists.infradead.org; Fri, 05 Aug 2011 06:44:02 +0000 Date: Fri, 5 Aug 2011 08:43:55 +0200 From: Sascha Hauer Message-ID: <20110805064355.GB31404@pengutronix.de> References: <1312468508-9205-1-git-send-email-antonynpavlov@gmail.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1312468508-9205-1-git-send-email-antonynpavlov@gmail.com> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: barebox-bounces@lists.infradead.org Errors-To: barebox-bounces+u.kleine-koenig=pengutronix.de@lists.infradead.org Subject: Re: [PATCH] serial_ns16550: switch to ns16550_priv structure To: Antony Pavlov Cc: barebox@lists.infradead.org Antony, Jean, Please stop fighting battles, there's enough work for all of us ;) On Thu, Aug 04, 2011 at 06:35:08PM +0400, Antony Pavlov wrote: > Signed-off-by: Antony Pavlov > --- > drivers/serial/serial_ns16550.c | 181 +++++++++++++++++++++++---------------- > drivers/serial/serial_ns16550.h | 16 ++++ > 2 files changed, 123 insertions(+), 74 deletions(-) > > diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c > index 36d39cd..a9f565e 100644 > --- a/drivers/serial/serial_ns16550.c > +++ b/drivers/serial/serial_ns16550.c > @@ -48,6 +48,42 @@ > > /*********** Private Functions **********************************/ > > +static unsigned int ns16550_generic_readb(unsigned long base, > + unsigned char reg_idx) > +{ > + return readb((char *)base + reg_idx); > +} Try building this with sparse enabled (make C=1): CHECK drivers/serial/serial_ns16550.c drivers/serial/serial_ns16550.c:54:16: warning: incorrect type in argument 1 (different address spaces) drivers/serial/serial_ns16550.c:54:16: expected void const volatile [noderef] * drivers/serial/serial_ns16550.c:54:16: got char * drivers/serial/serial_ns16550.c:60:9: warning: incorrect type in argument 1 (different address spaces) drivers/serial/serial_ns16550.c:60:9: expected void const volatile [noderef] * drivers/serial/serial_ns16550.c:60:9: got char * drivers/serial/serial_ns16550.c:66:16: warning: incorrect type in argument 1 (different address spaces) drivers/serial/serial_ns16550.c:66:16: expected void const volatile [noderef] * drivers/serial/serial_ns16550.c:66:16: got char * drivers/serial/serial_ns16550.c:72:9: warning: incorrect type in argument 1 (different address spaces) drivers/serial/serial_ns16550.c:72:9: expected void const volatile [noderef] * drivers/serial/serial_ns16550.c:72:9: got char * drivers/serial/serial_ns16550.c:78:16: warning: incorrect type in argument 1 (different address spaces) drivers/serial/serial_ns16550.c:78:16: expected void const volatile [noderef] * drivers/serial/serial_ns16550.c:78:16: got char * drivers/serial/serial_ns16550.c:84:9: warning: incorrect type in argument 1 (different address spaces) drivers/serial/serial_ns16550.c:84:9: expected void const volatile [noderef] * drivers/serial/serial_ns16550.c:84:9: got char * > + > +static void ns16550_generic_writeb(unsigned int val, unsigned long base, > + unsigned char reg_idx) > +{ > + writeb((0xff & val), (char *)base + reg_idx); > +} > + > +static unsigned int ns16550_generic_readw(unsigned long base, > + unsigned char reg_idx) > +{ > + return readw((char *)base + reg_idx); > +} > + > +static void ns16550_generic_writew(unsigned int val, unsigned long base, > + unsigned char reg_idx) > +{ > + writew((0xffff & val), (char *)base + reg_idx); > +} > + > +static unsigned int ns16550_generic_readl(unsigned long base, > + unsigned char reg_idx) > +{ > + return readl((char *)base + reg_idx); > +} > + > +static void ns16550_generic_writel(unsigned int val, unsigned long base, > + unsigned char reg_idx) > +{ > + writel(val, (char *)base + reg_idx); > +} > + > /** > * @brief read register > * > @@ -56,26 +92,9 @@ > * > * @return value > */ > -static uint32_t ns16550_read(struct console_device *cdev, uint32_t off) > +static inline uint32_t ns16550_read(struct ns16550_priv *priv, uint32_t off) > { > - struct device_d *dev = cdev->dev; > - struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data; > - int width = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK; > - > - off <<= plat->shift; > - > - if (plat->reg_read) > - return plat->reg_read((unsigned long)dev->priv, off); > - > - switch (width) { > - case IORESOURCE_MEM_8BIT: > - return readb(dev->priv + off); > - case IORESOURCE_MEM_16BIT: > - return readw(dev->priv + off); > - case IORESOURCE_MEM_32BIT: > - return readl(dev->priv + off); > - } > - return -1; > + return priv->reg_read((unsigned long)priv->base, off << priv->shift); > } > > /** > @@ -85,31 +104,10 @@ static uint32_t ns16550_read(struct console_device *cdev, uint32_t off) > * @param[in] offset > * @param[in] val > */ > -static void ns16550_write(struct console_device *cdev, uint32_t val, > +static inline void ns16550_write(struct ns16550_priv *priv, uint32_t val, > uint32_t off) > { > - struct device_d *dev = cdev->dev; > - struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data; > - int width = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK; > - > - off <<= plat->shift; > - > - if (plat->reg_write) { > - plat->reg_write(val, (unsigned long)dev->priv, off); > - return; > - } > - > - switch (width) { > - case IORESOURCE_MEM_8BIT: > - writeb(val & 0xff, dev->priv + off); > - break; > - case IORESOURCE_MEM_16BIT: > - writew(val & 0xffff, dev->priv + off); > - break; > - case IORESOURCE_MEM_32BIT: > - writel(val, dev->priv + off); > - break; > - } > + priv->reg_write(val, (unsigned long)priv->base, off << priv->shift); > } > > /** > @@ -120,15 +118,12 @@ static void ns16550_write(struct console_device *cdev, uint32_t val, > * > * @return divisor to be set > */ > -static unsigned int ns16550_calc_divisor(struct console_device *cdev, > +static unsigned int ns16550_calc_divisor(struct ns16550_priv *priv, > unsigned int baudrate) > { > - struct NS16550_plat *plat = (struct NS16550_plat *) > - cdev->dev->platform_data; > - unsigned int clk = plat->clock; > + unsigned int clk = priv->clock; > > return (clk / MODE_X_DIV / baudrate); > - > } > > /** > @@ -136,26 +131,26 @@ static unsigned int ns16550_calc_divisor(struct console_device *cdev, > * > * @param[in] cdev pointer to console device > */ > -static void ns16550_serial_init_port(struct console_device *cdev) > +static void ns16550_serial_init_port(struct ns16550_priv *priv) > { > unsigned int baud_divisor; > > /* Setup the serial port with the defaults first */ > - baud_divisor = ns16550_calc_divisor(cdev, CONFIG_BAUDRATE); > + baud_divisor = ns16550_calc_divisor(priv, CONFIG_BAUDRATE); > > /* initializing the device for the first time */ > - ns16550_write(cdev, 0x00, ier); > + ns16550_write(priv, 0x00, ier); > #ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS > - ns16550_write(cdev, 0x07, mdr1); /* Disable */ > + ns16550_write(priv, 0x07, mdr1); /* Disable */ > #endif > - ns16550_write(cdev, LCR_BKSE | LCRVAL, lcr); > - ns16550_write(cdev, baud_divisor & 0xFF, dll); > - ns16550_write(cdev, (baud_divisor >> 8) & 0xff, dlm); > - ns16550_write(cdev, LCRVAL, lcr); > - ns16550_write(cdev, MCRVAL, mcr); > - ns16550_write(cdev, FCRVAL, fcr); > + ns16550_write(priv, LCR_BKSE | LCRVAL, lcr); > + ns16550_write(priv, baud_divisor & 0xFF, dll); > + ns16550_write(priv, (baud_divisor >> 8) & 0xff, dlm); > + ns16550_write(priv, LCRVAL, lcr); > + ns16550_write(priv, MCRVAL, mcr); > + ns16550_write(priv, FCRVAL, fcr); > #ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS > - ns16550_write(cdev, 0x00, mdr1); > + ns16550_write(priv, 0x00, mdr1); > #endif > } > > @@ -169,9 +164,11 @@ static void ns16550_serial_init_port(struct console_device *cdev) > */ > static void ns16550_putc(struct console_device *cdev, char c) > { > + struct ns16550_priv *priv = cdev->dev->priv; > + > /* Loop Doing Nothing */ > - while ((ns16550_read(cdev, lsr) & LSR_THRE) == 0) ; > - ns16550_write(cdev, c, thr); > + while ((ns16550_read(priv, lsr) & LSR_THRE) == 0) ; > + ns16550_write(priv, c, thr); > } > > /** > @@ -183,9 +180,12 @@ static void ns16550_putc(struct console_device *cdev, char c) > */ > static int ns16550_getc(struct console_device *cdev) > { > + struct ns16550_priv *priv = cdev->dev->priv; > + > /* Loop Doing Nothing */ > - while ((ns16550_read(cdev, lsr) & LSR_DR) == 0) ; > - return ns16550_read(cdev, rbr); > + while ((ns16550_read(priv, lsr) & LSR_DR) == 0) ; > + > + return ns16550_read(priv, rbr); > } > > /** > @@ -197,7 +197,9 @@ static int ns16550_getc(struct console_device *cdev) > */ > static int ns16550_tstc(struct console_device *cdev) > { > - return ((ns16550_read(cdev, lsr) & LSR_DR) != 0); > + struct ns16550_priv *priv = cdev->dev->priv; > + > + return ((ns16550_read(priv, lsr) & LSR_DR) != 0); > } > > /** > @@ -210,15 +212,16 @@ static int ns16550_tstc(struct console_device *cdev) > */ > static int ns16550_setbaudrate(struct console_device *cdev, int baud_rate) > { > - unsigned int baud_divisor = ns16550_calc_divisor(cdev, baud_rate); > - > - ns16550_write(cdev, 0x00, ier); > - ns16550_write(cdev, LCR_BKSE, lcr); > - ns16550_write(cdev, baud_divisor & 0xff, dll); > - ns16550_write(cdev, (baud_divisor >> 8) & 0xff, dlm); > - ns16550_write(cdev, LCRVAL, lcr); > - ns16550_write(cdev, MCRVAL, mcr); > - ns16550_write(cdev, FCRVAL, fcr); > + struct ns16550_priv *priv = cdev->dev->priv; > + unsigned int baud_divisor = ns16550_calc_divisor(priv, baud_rate); > + > + ns16550_write(priv, 0x00, ier); > + ns16550_write(priv, LCR_BKSE, lcr); > + ns16550_write(priv, baud_divisor & 0xff, dll); > + ns16550_write(priv, (baud_divisor >> 8) & 0xff, dlm); > + ns16550_write(priv, LCRVAL, lcr); > + ns16550_write(priv, MCRVAL, mcr); > + ns16550_write(priv, FCRVAL, fcr); > return 0; > } > > @@ -235,11 +238,11 @@ static int ns16550_probe(struct device_d *dev) > { > struct console_device *cdev; > struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data; > + struct ns16550_priv *priv; > > /* we do expect platform specific data */ > if (plat == NULL) > return -EINVAL; > - dev->priv = dev_request_mem_region(dev, 0); > > cdev = xzalloc(sizeof(*cdev)); > > @@ -254,7 +257,37 @@ static int ns16550_probe(struct device_d *dev) > cdev->getc = ns16550_getc; > cdev->setbrg = ns16550_setbaudrate; > > - ns16550_serial_init_port(cdev); > + priv = xzalloc(sizeof(struct ns16550_priv)); > + dev->priv = priv; > + priv->base = dev_request_mem_region(dev, 0); > + > + if (plat->reg_read != NULL && plat->reg_write != NULL) { > + priv->reg_read = plat->reg_read; > + priv->reg_write = plat->reg_write; > + } else { > + int width = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK; > + > + switch (width) { > + default: > + case IORESOURCE_MEM_8BIT: > + priv->reg_read = ns16550_generic_readb; > + priv->reg_write = ns16550_generic_writeb; > + break; > + case IORESOURCE_MEM_16BIT: > + priv->reg_read = ns16550_generic_readw; > + priv->reg_write = ns16550_generic_writew; > + break; > + case IORESOURCE_MEM_32BIT: > + priv->reg_read = ns16550_generic_readl; > + priv->reg_write = ns16550_generic_writel; > + break; > + } > + } > + > + priv->clock = plat->clock; > + priv->shift = plat->shift; > + > + ns16550_serial_init_port(priv); > > return console_register(cdev); > } > diff --git a/drivers/serial/serial_ns16550.h b/drivers/serial/serial_ns16550.h > index db8fe64..538d522 100644 > --- a/drivers/serial/serial_ns16550.h > +++ b/drivers/serial/serial_ns16550.h > @@ -29,6 +29,22 @@ > #ifndef __SERIAL_NS16550__H > #define __SERIAL_NS16550__H > > +struct ns16550_priv { > + unsigned char __iomem *base; > + /** > + * register read access capability > + */ > + unsigned int (*reg_read) (unsigned long base, unsigned char reg_offset); > + /** > + * register write access capability > + */ > + void (*reg_write) (unsigned int val, unsigned long base, > + unsigned char reg_offset); > + > + int shift; > + unsigned int clock; > +}; > + > /** Register offset definitions > * platform implementation needs to translate this > */ > -- > 1.7.5.4 > > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox