On 01/06/2019 21:20, Vijay Kumar Banerjee wrote:
> ---
>  libbsd.py                |   1 +
>  rtemsbsd/i2c/rtems-i2c.c | 218 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 219 insertions(+)
>  create mode 100644 rtemsbsd/i2c/rtems-i2c.c

I think the file would be better located at
    rtemsbsd/sys/dev/iicbus/rtems-i2c.c

The directory structure for drivers should be similar to the one in FreeBSD.

> 
> diff --git a/libbsd.py b/libbsd.py
> index a25d3a8a..6e8ff987 100644
> --- a/libbsd.py
> +++ b/libbsd.py
> @@ -771,6 +771,7 @@ class iic(builder.Module):
>          self.addRTEMSSourceFiles(
>              [
>                  'local/iicbus_if.c',
> +                'i2c/rtems-i2c.c',
>              ],
>              mm.generator['source']()
>          )
> diff --git a/rtemsbsd/i2c/rtems-i2c.c b/rtemsbsd/i2c/rtems-i2c.c
> new file mode 100644
> index 00000000..5189e5fe
> --- /dev/null
> +++ b/rtemsbsd/i2c/rtems-i2c.c
> @@ -0,0 +1,218 @@
> +/*
> + * Copyright (c) 2019 Vijay Kumar Banerjee <vijaykumar9...@gmail.com>.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +#include <machine/rtems-bsd-kernel-space.h>
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <fcntl.h>
> +
> +#include <sys/module.h>
> +#include <sys/param.h>
> +#include <sys/kernel.h>
> +#include <sys/errno.h>
> +#include <sys/bus.h>
> +
> +#include <dev/iicbus/iicbus.h>
> +#include <dev/iicbus/iic.h>
> +#include <dev/iicbus/iiconf.h>
> +#include <dev/ofw/ofw_bus.h>
> +#include <dev/ofw/ofw_bus_subr.h>
> +#include <dev/ofw/openfirm.h>
> +
> +#include <rtems/bsd/local/iicbus_if.h>
> +
> +#include <linux/i2c.h>
> +#include <linux/i2c-dev.h>
> +
> +typedef struct i2c_msg i2c_msg;
> +
> +struct i2c_softc {
> +     device_t dev;
> +     device_t sc_iicbus;
> +     char *path;
> +     int fd;
> +     int mem_rid;
> +     int irq_rid;

mem_rid and irq_rid seem to be unused.

> +};
> +
> +static int
> +rtems_i2c_probe(device_t dev)
> +{
> +     if (!ofw_bus_status_okay(dev)) {
> +             return (ENXIO);
> +     }
> +     if (!ofw_bus_is_compatible(dev, "rtems,bsp-i2c")){
> +             return (ENXIO);
> +     }
> +
> +     device_set_desc(dev, "RTEMS libbsd I2C");
> +     return (BUS_PROBE_SPECIFIC);
> +}
> +
> +static int
> +rtems_i2c_attach(device_t dev)
> +{
> +     phandle_t node;
> +     ssize_t compatlen;
> +     char *compat;
> +     char *curstr;
> +     struct i2c_softc *sc;
> +     int len;
> +
> +     sc = device_get_softc(dev);
> +     sc->dev = dev;
> +     node = ofw_bus_get_node(sc->dev);
> +
> +     len = OF_getprop_alloc(node, "rtems,i2c-path", &sc->path);
> +     if (len == -1){
> +             device_printf(sc->dev, "Path not found in Device Tree");
> +             OF_prop_free(sc->path);
> +             return (ENXIO);
> +     }
> +     else{

You don't really need the else here. If your error case hits, you return
anyway. So you can save one level of indentation for the next block.

> +             if ((sc->sc_iicbus = device_add_child(sc->dev, "iicbus", -1)) 
> == NULL) {
> +                     device_printf(sc->dev, "could not allocate iicbus 
> instance\n");
> +                     OF_prop_free(sc->path);
> +                     return (ENXIO);
> +             }
> +             config_intrhook_oneshot((ich_func_t)bus_generic_attach, 
> sc->dev);
> +     }
> +     return (0);
> +}
> +
> +static int
> +rtems_i2c_detach(device_t dev)
> +{
> +     struct i2c_softc *sc;
> +     int error;
> +
> +     sc = device_get_softc(dev);
> +
> +     OF_prop_free(sc->path);
> +
> +     if (sc->sc_iicbus && (error = device_delete_child(dev, sc->sc_iicbus)) 
> != 0)
> +             return (error);
> +
> +     if ((error = bus_generic_detach(sc->dev)) != 0) {
> +             device_printf(sc->dev, "cannot detach child devices\n");
> +             return (error);
> +     }

Maybe we misunderstood each other there in our chat: The detach should
have roughly a reverse order of the attach. The last action in your
attach is the bus_generic_attach so the first one in detach should be
the bus_generic_detach.

> +
> +
> +     return (0);
> +}
> +
> +static int
> +rtems_i2c_transfer(device_t dev, struct iic_msg *msgs, u_int num)
> +{
> +     i2c_msg *messages;
> +     int err;
> +     char *addr;
> +     struct i2c_softc *sc;
> +     struct i2c_rdwr_ioctl_data ioctl_data;
> +
> +     sc = device_get_softc(dev);
> +
> +     /* Open /dev/iic0 */
> +     sc->fd = open(sc->path, O_RDWR);

Why save the fd in the softc if you only use it in this function? You
can use a local variable here.

> +     if (sc->fd < 0) {
> +             device_printf(sc->dev, "%s\n", strerror(errno));
> +             return errno;
> +     }
> +
> +     /* cast iic_msg to i2c_msg */
> +     messages = (i2c_msg *) msgs;
> +     ioctl_data.msgs = messages;
> +     ioctl_data.nmsgs = num;
> +
> +     /* IOCTL call to write */
> +     err = ioctl(sc->fd, I2C_RDWR, &ioctl_data);
> +     if (err < 0){
> +             device_printf(sc->dev, "%s\n", strerror(errno));
> +             close(sc->fd);
> +             return errno;
> +     }
> +
> +     /* Close the device */
> +     close(sc->fd);
> +
> +     return (0);
> +}
> +
> +static int
> +rtems_i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
> +{
> +     return (0);
> +}
> +
> +static phandle_t
> +rtems_i2c_get_node(device_t bus, device_t dev)
> +{
> +
> +     /* Share controller node with iibus device. */
> +     return (ofw_bus_get_node(bus));
> +}
> +
> +static device_method_t rtems_i2c_methods[] = {
> +     /* Device Interface */
> +     DEVMETHOD(device_probe,         rtems_i2c_probe),
> +     DEVMETHOD(device_attach,        rtems_i2c_attach),
> +     DEVMETHOD(device_detach,        rtems_i2c_detach),
> +
> +     /* Bus interface */
> +     DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
> +     DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
> +     DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
> +     DEVMETHOD(bus_release_resource, bus_generic_release_resource),
> +     DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
> +     DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
> +     DEVMETHOD(bus_adjust_resource,  bus_generic_adjust_resource),
> +     DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
> +     DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
> +
> +     /* OFW methods */
> +     DEVMETHOD(ofw_bus_get_node, rtems_i2c_get_node),
> +
> +     /* iicbus interface */
> +     DEVMETHOD(iicbus_callback,      iicbus_null_callback),
> +     DEVMETHOD(iicbus_reset,         rtems_i2c_reset),
> +     DEVMETHOD(iicbus_transfer,      rtems_i2c_transfer),
> +
> +     DEVMETHOD_END
> +};
> +
> +static driver_t rtems_i2c_driver = {
> +     "rtems_i2c",
> +     rtems_i2c_methods,
> +     sizeof(struct i2c_softc),
> +};
> +
> +static devclass_t rtems_i2c_devclass;
> +DRIVER_MODULE(rtems_i2c, simplebus, rtems_i2c_driver, rtems_i2c_devclass, 0, 
> 0);
> +DRIVER_MODULE(iicbus, rtems_i2c, iicbus_driver, iicbus_devclass, 0, 0);
> +DRIVER_MODULE(ofw_iicbus, rtems_i2c, ofw_iicbus_driver, ofw_iicbus_devclass, 
> 0, 0);
> 

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to