[PATCH linux v1 4/8] drivers: fsi: Add i2c client driver

Joel Stanley joel at jms.id.au
Fri Feb 3 11:58:51 AEDT 2017


On Fri, Feb 3, 2017 at 11:26 AM, Alistair Popple <alistair at popple.id.au> wrote:
> Hi Edward,
>
> On Thu, 2 Feb 2017 05:25:57 PM eajames at linux.vnet.ibm.com wrote:
>> From: "Edward A. James" <eajames at us.ibm.com>
>>
>> stub for I2C driver over FSI
>
> Unless I've missed something it doesn't look like this uses any of the
> existing I2C infrastructure in the kernel. This should live in
> drivers/i2c/busses and register the I2C bus adapter using
> i2c_add_adapter(). This way all the existing kernel infrastructe for
> probing and assiging I2C device drivers can be utilised.
>
> For an example see how OPAL currently exposes I2C busses on the host
> in drivers/i2c/busses/i2c-opal.c.

Alistair is right on the money. This should have never seen the light of day.

Alistair, and others: we did agree that due to this functionality
being required in short order, and a proper driver not being started
yet, we will merge these patches temporarily.

Eddie and Chris will be working with me to write a proper i2c driver on Monday.

Cheers,

Joel

>
> Regards,
>
> Alistair
>
>> Signed-off-by: Edward A. James <eajames at us.ibm.com>
>> ---
>>  drivers/fsi/Kconfig       |   6 ++
>>  drivers/fsi/Makefile      |   1 +
>>  drivers/fsi/i2c/Makefile  |   1 +
>>  drivers/fsi/i2c/iic-fsi.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++
>>  drivers/fsi/i2c/iic-fsi.h |  29 ++++++++
>>  drivers/fsi/i2c/iic-int.h |  80 ++++++++++++++++++++++
>>  6 files changed, 283 insertions(+)
>>  create mode 100644 drivers/fsi/i2c/Makefile
>>  create mode 100644 drivers/fsi/i2c/iic-fsi.c
>>  create mode 100644 drivers/fsi/i2c/iic-fsi.h
>>  create mode 100644 drivers/fsi/i2c/iic-int.h
>>
>> diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
>> index 0fa265c..c78b9b6e 100644
>> --- a/drivers/fsi/Kconfig
>> +++ b/drivers/fsi/Kconfig
>> @@ -24,6 +24,12 @@ config FSI_SCOM
>>       ---help---
>>       This option enables an FSI based SCOM device driver.
>>
>> +config FSI_I2C
>> +     tristate "I2C FSI client device driver"
>> +     depends on FSI
>> +     ---help---
>> +     This option enables an FSI based I2C device driver.
>> +
>>  endif
>>
>>  endmenu
>> diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile
>> index 3466f08..3a106ba 100644
>> --- a/drivers/fsi/Makefile
>> +++ b/drivers/fsi/Makefile
>> @@ -2,3 +2,4 @@
>>  obj-$(CONFIG_FSI) += fsi-core.o
>>  obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o
>>  obj-$(CONFIG_FSI_SCOM) += fsi-scom.o
>> +obj-$(CONFIG_FSI_I2C) += i2c/
>> diff --git a/drivers/fsi/i2c/Makefile b/drivers/fsi/i2c/Makefile
>> new file mode 100644
>> index 0000000..f9f9048
>> --- /dev/null
>> +++ b/drivers/fsi/i2c/Makefile
>> @@ -0,0 +1 @@
>> +obj-$(CONFIG_FSI_I2C) += iic-fsi.o
>> diff --git a/drivers/fsi/i2c/iic-fsi.c b/drivers/fsi/i2c/iic-fsi.c
>> new file mode 100644
>> index 0000000..51a15a4
>> --- /dev/null
>> +++ b/drivers/fsi/i2c/iic-fsi.c
>> @@ -0,0 +1,166 @@
>> +/*
>> + *   Copyright (c) International Business Machines Corp., 2006, 2010, 2012
>> + *
>> + *   This program is free software;  you can redistribute it and/or modify
>> + *   it under the terms of the GNU General Public License as published by
>> + *   the Free Software Foundation; either version 2 of the License, or
>> + *   (at your option) any later version.
>> + *
>> + *   This program is distributed in the hope that it will be useful,
>> + *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
>> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>> + *   the GNU General Public License for more details.
>> + *
>> + *   You should have received a copy of the GNU General Public License
>> + *   along with this program;  if not, write to the Free Software
>> + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
>> + */
>> +
>> +/*
>> + * This file contains the architecture independent IIC FSI code.
>> + */
>> +#include <linux/init.h>
>> +#include <linux/module.h>
>> +#include <linux/kernel.h>
>> +#include <linux/slab.h>
>> +#include <linux/fsi.h>
>> +#include <asm/io.h>
>> +#include <linux/mm.h>
>> +#include <linux/interrupt.h>
>> +#include "iic-int.h"
>> +#include "iic-fsi.h"
>> +
>> +#include <linux/delay.h>
>> +#include <linux/moduleparam.h>
>> +
>> +struct class* iic_fsi_class = 0;
>> +dev_t iic_devnum_start = 0;
>> +
>> +static const char iic_fsi_version[] = "3.0";
>> +
>> +int iic_fsi_probe(struct device *dev);
>> +int iic_fsi_remove(struct device *dev);
>> +
>> +struct iic_reg_access fsi_reg_access =
>> +{
>> +     .bus_readb = readb_wrap,
>> +     .bus_readh = readh_wrap,
>> +     .bus_readw = readw_wrap,
>> +     .bus_writeb = writeb_wrap,
>> +     .bus_writeh = writeh_wrap,
>> +     .bus_writew = writew_wrap,
>> +};
>> +
>> +static const struct fsi_device_id i2c_ids[] = {
>> +     {
>> +             .engine_type = FSI_ENGID_I2C,
>> +             .version = FSI_VERSION_ANY,
>> +     },
>> +     {
>> +             .engine_type = FSI_ENGID_I2C_BB,
>> +             .version = FSI_VERSION_ANY,
>> +     },
>> +     { 0 }
>> +};
>> +
>> +static const struct fsi_driver i2c_drv = {
>> +     .id_table = i2c_ids,
>> +     .drv = {
>> +             .name = "iic_fsi_dd",
>> +             .bus = &fsi_bus_type,
>> +             .probe = iic_fsi_probe,
>> +             .remove = iic_fsi_remove,
>> +     }
>> +};
>> +
>> +/*
>> + * Called when an FSI IIC engine is plugged in.
>> + * Causes creation of the /dev entry.
>> + * Not allowed to access engine registers in this function.
>> + *
>> + */
>> +int iic_fsi_probe(struct device *dev)
>> +{
>> +     return 0;
>> +}
>> +
>> +/* This function is called when a link is removed or the driver is unloaded.
>> + * It's job is to remove the device from the device hierarchy including
>> + * removal from sysfs (this is where device files get removed).
>> + */
>> +int iic_fsi_remove(struct device* dev)
>> +{
>> +     return 0;
>> +}
>> +
>> +/*
>> + * Initialize this module.  Creates a class for fsi connected iic devices and
>> + * allocates device numbers for them.
>> + */
>> +static int __init iic_fsi_init(void)
>> +{
>> +     int rc = 0;
>> +
>> +     IENTER();
>> +
>> +     rc = alloc_chrdev_region(&iic_devnum_start,
>> +                     0, /*starting minor number*/
>> +                     IIC_FSI_MAX_DEVS,
>> +                     "iic-fsi");
>> +     if(rc)
>> +     {
>> +              IFLDe(1, "master alloc_chrdev_region failed: rc = %d\n", rc);
>> +              return rc;
>> +     }
>> +
>> +     iic_fsi_class = class_create(THIS_MODULE, "iic-fsi");
>> +     if (IS_ERR(iic_fsi_class))
>> +     {
>> +             IFLDe(1, "class_create failed: rc=%ld",
>> +                             PTR_ERR(iic_fsi_class));
>> +             goto exit_class_create;
>> +     }
>> +     /* Register this driver with the FSI infrastructure */
>> +     rc = fsi_driver_register(&i2c_drv);
>> +     if(rc)
>> +     {
>> +             IFLDe(1, "fsidrv_register failed: %d", rc);
>> +             goto exit_drv_register;
>> +     }
>> +
>> +     printk("IIC FSI support loaded, ver. %s\n", iic_fsi_version);
>> +
>> +     IEXIT(rc);
>> +     return rc;
>> +
>> +exit_drv_register:
>> +     class_destroy(iic_fsi_class);
>> +exit_class_create:
>> +     unregister_chrdev_region(iic_devnum_start, IIC_FSI_MAX_DEVS);
>> +     IEXIT(rc);
>> +     return rc;
>> +}
>> +
>> +static void __exit iic_fsi_exit(void)
>> +{
>> +     IENTER();
>> +     IDBGd(0, "fisdrv_unregister()\n");
>> +     fsi_driver_unregister(&i2c_drv);
>> +     IDBGd(0, "unregister_chrdev_region()\n");
>> +     unregister_chrdev_region(iic_devnum_start, IIC_FSI_MAX_DEVS);
>> +     if(iic_fsi_class)
>> +     {
>> +             IDBGd(0, "class_destroy\n");
>> +             class_destroy(iic_fsi_class);
>> +     }
>> +     printk("IIC FSI support unloaded.\n");
>> +     IEXIT(0);
>> +}
>> +
>> +module_init(iic_fsi_init);
>> +module_exit(iic_fsi_exit);
>> +
>> +MODULE_AUTHOR("Eddie James <eajames at us.ibm.com>");
>> +MODULE_DESCRIPTION("IIC FSI Driver");
>> +MODULE_LICENSE("GPL");
>> +
>> diff --git a/drivers/fsi/i2c/iic-fsi.h b/drivers/fsi/i2c/iic-fsi.h
>> new file mode 100644
>> index 0000000..4decb2c
>> --- /dev/null
>> +++ b/drivers/fsi/i2c/iic-fsi.h
>> @@ -0,0 +1,29 @@
>> +/*
>> + *   Copyright (c) International Business Machines Corp., 2006
>> + *
>> + *   This program is free software;  you can redistribute it and/or modify
>> + *   it under the terms of the GNU General Public License as published by
>> + *   the Free Software Foundation; either version 2 of the License, or
>> + *   (at your option) any later version.
>> + *
>> + *   This program is distributed in the hope that it will be useful,
>> + *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
>> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>> + *   the GNU General Public License for more details.
>> + *
>> + *   You should have received a copy of the GNU General Public License
>> + *   along with this program;  if not, write to the Free Software
>> + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
>> + */
>> +
>> +#ifndef IIC_FSI_H
>> +#define IIC_FSI_H
>> +
>> +/*
>> + * we don't know ahead of time how many minors will be needed as this is based
>> + * on platform type and the possibility of sparsely populated FRU's on special
>> + * systems so picking a safely large number
>> + */
>> +#define IIC_FSI_MAX_DEVS     1024
>> +
>> +#endif
>> diff --git a/drivers/fsi/i2c/iic-int.h b/drivers/fsi/i2c/iic-int.h
>> new file mode 100644
>> index 0000000..545b2c3
>> --- /dev/null
>> +++ b/drivers/fsi/i2c/iic-int.h
>> @@ -0,0 +1,80 @@
>> +/*
>> + *   Copyright (c) International Business Machines Corp., 2006, 2012
>> + *
>> + *   This program is free software;  you can redistribute it and/or modify
>> + *   it under the terms of the GNU General Public License as published by
>> + *   the Free Software Foundation; either version 2 of the License, or
>> + *   (at your option) any later version.
>> + *
>> + *   This program is distributed in the hope that it will be useful,
>> + *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
>> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>> + *   the GNU General Public License for more details.
>> + *
>> + *   You should have received a copy of the GNU General Public License
>> + *   along with this program;  if not, write to the Free Software
>> + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
>> + */
>> +
>> +#ifndef IIC_INT_H
>> +#define IIC_INT_H
>> +#include <linux/list.h>
>> +#include <linux/spinlock.h>
>> +#include <linux/fs.h>
>> +#include <linux/kobject.h>
>> +#include <linux/cdev.h>
>> +#include <linux/device.h>
>> +#include <linux/kdev_t.h>
>> +#include <linux/wait.h>
>> +#include <linux/i2cfsi.h>
>> +#include <linux/semaphore.h>
>> +#include <linux/fsi.h>
>> +#include <asm/atomic.h>
>> +
>> +#define FSI_ENGID_I2C                0x7
>> +#define FSI_ENGID_I2C_BB     0x17
>> +
>> +#ifdef FSI_I2C_DEBUG
>> +#define IDBGs(num, msg, args...) printk(msg, ## args)
>> +#define IDBGd(num, msg, args...) printk(msg, ## args)
>> +#define IDBGf(num, msg, args...) printk(msg, ## args)
>> +#define IDBGl(num, msg, args...) printk(msg, ## args)
>> +#else
>> +#define IDBGs(num, msg, args...)
>> +#define IDBGd(num, msg, args...)
>> +#define IDBGf(num, msg, args...)
>> +#define IDBGl(num, msg, args...)
>> +#endif
>> +
>> +#define IENTER()
>> +#define IEXIT(RC)
>> +
>> +/* IFLDx traces will not get compiled out */
>> +#define IFLDe(num, msg, args...)\
>> +     printk("ERR: "msg, ## args)
>> +#define IFLDi(num, msg, args...)\
>> +     printk(msg, ## args)
>> +
>> +#ifdef FSI_I2C_DEBUG
>> +#define IFLDs(num, msg, args...) printk(msg, ## args)
>> +#define IFLDd(num, msg, args...) printk(msg, ## args)
>> +#define IFLDf(num, msg, args...) printk(msg, ## args)
>> +#define IFLDl(num, msg, args...) printk(msg, ## args)
>> +#else
>> +#define IFLDs(num, msg, args...)
>> +#define IFLDd(num, msg, args...)
>> +#define IFLDf(num, msg, args...)
>> +#define IFLDl(num, msg, args...)
>> +#endif
>> +
>> +struct iic_reg_access
>> +{
>> +    int (*bus_readb)(iic_eng_t*, unsigned int, unsigned char*, iic_ffdc_t**);
>> +    int (*bus_readh)(iic_eng_t*, unsigned int, unsigned short*, iic_ffdc_t**);
>> +    int (*bus_readw)(iic_eng_t*, unsigned int, unsigned long*, iic_ffdc_t**);
>> +    int (*bus_writeb)(iic_eng_t*, unsigned int, unsigned char, iic_ffdc_t**);
>> +    int (*bus_writeh)(iic_eng_t*, unsigned int, unsigned short, iic_ffdc_t**);
>> +    int (*bus_writew)(iic_eng_t*, unsigned int, unsigned long, iic_ffdc_t**);
>> +};
>> +
>> +#endif
>>
>


More information about the openbmc mailing list