From 1b0087eb82e110b24893c83959ab375ed8b3f44b Mon Sep 17 00:00:00 2001 From: Vaishnav M A Date: Wed, 21 Oct 2020 02:20:29 +0530 Subject: [PATCH] mikrobus driver update, serdev patches --- patch.sh | 2 + ...2563-change-of_property_read-to-devi.patch | 72 +++ ...iio-light-vcnl4035-add-i2c_device_id.patch | 51 ++ ...ximity-vl53l0x-i2c-add-i2c_device_id.patch | 52 ++ ...> 0001-mikrobus-driver-update-patch.patch} | 531 ++++++++++-------- .../mikrobus/0002-mikroBUS-build-fixes.patch | 64 --- .../0001-serdev-Add-serdev_device_id.patch | 159 ++++++ ...ile2alias-Support-for-serdev-devices.patch | 70 +++ ...-of_-helper-to-get-serdev-controller.patch | 70 +++ ...s-ubx-add-MODULE_DEVICE_TABLE-serdev.patch | 42 ++ ...roperty_read-to-device_property_read.patch | 35 ++ 11 files changed, 837 insertions(+), 311 deletions(-) create mode 100644 patches/drivers/iio/v4-0001-iio-light-tsl2563-change-of_property_read-to-devi.patch create mode 100644 patches/drivers/iio/v4-0001-iio-light-vcnl4035-add-i2c_device_id.patch create mode 100644 patches/drivers/iio/v4-0001-iio-proximity-vl53l0x-i2c-add-i2c_device_id.patch rename patches/drivers/mikrobus/{0001-RFC-mikroBUS-driver-for-add-on-boards.patch => 0001-mikrobus-driver-update-patch.patch} (89%) delete mode 100644 patches/drivers/mikrobus/0002-mikroBUS-build-fixes.patch create mode 100644 patches/drivers/serdev/0001-serdev-Add-serdev_device_id.patch create mode 100644 patches/drivers/serdev/0002-file2alias-Support-for-serdev-devices.patch create mode 100644 patches/drivers/serdev/0003-serdev-add-of_-helper-to-get-serdev-controller.patch create mode 100644 patches/drivers/serdev/0004-gnss-ubx-add-MODULE_DEVICE_TABLE-serdev.patch create mode 100644 patches/drivers/serdev/0005-gnss-change-of_property_read-to-device_property_read.patch diff --git a/patch.sh b/patch.sh index 628ad13e4b..b5d8f70f43 100644 --- a/patch.sh +++ b/patch.sh @@ -383,6 +383,8 @@ drivers () { dir 'drivers/ti/gpio' dir 'drivers/greybus' dir 'drivers/mikrobus' + dir 'drivers/serdev' + dir 'drivers/iio' } soc () { diff --git a/patches/drivers/iio/v4-0001-iio-light-tsl2563-change-of_property_read-to-devi.patch b/patches/drivers/iio/v4-0001-iio-light-tsl2563-change-of_property_read-to-devi.patch new file mode 100644 index 0000000000..4a04acb14f --- /dev/null +++ b/patches/drivers/iio/v4-0001-iio-light-tsl2563-change-of_property_read-to-devi.patch @@ -0,0 +1,72 @@ +From d06a613f485a380674645d2358ac6d189040a766 Mon Sep 17 00:00:00 2001 +From: Vaishnav M A +Date: Thu, 15 Oct 2020 16:12:05 +0530 +Subject: [PATCH v4] iio:light:tsl2563 use generic fw accessors + +Replace of_property_read_u32() with device_property_read_u32(), +when reading the amstaos,cover-comp-gain.This opens up the +possibility of passing the properties during platform instantiation +of the device by a suitable populated struct property_entry. +Additionally, a minor change in logic is added to remove the +of_node present check. + +Signed-off-by: Vaishnav M A +--- + v4: + -update commit message, fix punctuation. + -update to a shorter commit title, used for similar changes + within the subsystem, like in 00fa493b9989 + ("iio:proximity:as3935: Drop of_match_ptr and use generic fw accessors") + v3: + -modify commit message for readability, mention minor logic change + -include mod_devicetable.h and property.h headers + v2: + -fix commit message + drivers/iio/light/tsl2563.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c +index abc8d7db8dc1..5bf2bfbc5379 100644 +--- a/drivers/iio/light/tsl2563.c ++++ b/drivers/iio/light/tsl2563.c +@@ -12,6 +12,8 @@ + */ + + #include ++#include ++#include + #include + #include + #include +@@ -703,7 +705,6 @@ static int tsl2563_probe(struct i2c_client *client, + struct iio_dev *indio_dev; + struct tsl2563_chip *chip; + struct tsl2563_platform_data *pdata = client->dev.platform_data; +- struct device_node *np = client->dev.of_node; + int err = 0; + u8 id = 0; + +@@ -738,13 +739,14 @@ static int tsl2563_probe(struct i2c_client *client, + chip->calib0 = tsl2563_calib_from_sysfs(CALIB_BASE_SYSFS); + chip->calib1 = tsl2563_calib_from_sysfs(CALIB_BASE_SYSFS); + +- if (pdata) ++ if (pdata) { + chip->cover_comp_gain = pdata->cover_comp_gain; +- else if (np) +- of_property_read_u32(np, "amstaos,cover-comp-gain", +- &chip->cover_comp_gain); +- else +- chip->cover_comp_gain = 1; ++ } else { ++ err = device_property_read_u32(&client->dev, "amstaos,cover-comp-gain", ++ &chip->cover_comp_gain); ++ if (err) ++ chip->cover_comp_gain = 1; ++ } + + dev_info(&client->dev, "model %d, rev. %d\n", id >> 4, id & 0x0f); + indio_dev->name = client->name; +-- +2.25.1 + diff --git a/patches/drivers/iio/v4-0001-iio-light-vcnl4035-add-i2c_device_id.patch b/patches/drivers/iio/v4-0001-iio-light-vcnl4035-add-i2c_device_id.patch new file mode 100644 index 0000000000..088b475ebc --- /dev/null +++ b/patches/drivers/iio/v4-0001-iio-light-vcnl4035-add-i2c_device_id.patch @@ -0,0 +1,51 @@ +From dbbed44fe8fb51d0e9be598ff05825609df9f6ce Mon Sep 17 00:00:00 2001 +From: Vaishnav M A +Date: Thu, 15 Oct 2020 16:12:06 +0530 +Subject: [PATCH v4] iio: light: vcnl4035 add i2c_device_id + +Add i2c_device_id table for the vcnl4035 driver, +enabling device instantiation using i2c_new_client_device() +or from userspace in cases where device-tree based description +is not possible now, like device(s) on a gbphy i2c_adapter +created by greybus. + +Signed-off-by: Vaishnav M A +--- + v4: + -update commit message, add punctuation. + v3: + -modify commit message for readability + as suggested by Jonathan Cameron + v2: + -fix commit message + drivers/iio/light/vcnl4035.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c +index 765c44adac57..73a28e30dddc 100644 +--- a/drivers/iio/light/vcnl4035.c ++++ b/drivers/iio/light/vcnl4035.c +@@ -652,6 +652,12 @@ static const struct dev_pm_ops vcnl4035_pm_ops = { + vcnl4035_runtime_resume, NULL) + }; + ++static const struct i2c_device_id vcnl4035_id[] = { ++ { "vcnl4035", 0}, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, vcnl4035_id); ++ + static const struct of_device_id vcnl4035_of_match[] = { + { .compatible = "vishay,vcnl4035", }, + { } +@@ -666,6 +672,7 @@ static struct i2c_driver vcnl4035_driver = { + }, + .probe = vcnl4035_probe, + .remove = vcnl4035_remove, ++ .id_table = vcnl4035_id, + }; + + module_i2c_driver(vcnl4035_driver); +-- +2.25.1 + diff --git a/patches/drivers/iio/v4-0001-iio-proximity-vl53l0x-i2c-add-i2c_device_id.patch b/patches/drivers/iio/v4-0001-iio-proximity-vl53l0x-i2c-add-i2c_device_id.patch new file mode 100644 index 0000000000..6cf1ad01a0 --- /dev/null +++ b/patches/drivers/iio/v4-0001-iio-proximity-vl53l0x-i2c-add-i2c_device_id.patch @@ -0,0 +1,52 @@ +From 8a6cba6d5c4ebfe53c18ae2b2ce534c4fc68c417 Mon Sep 17 00:00:00 2001 +From: Vaishnav M A +Date: Thu, 15 Oct 2020 16:12:06 +0530 +Subject: [PATCH v4] iio: proximity: vl53l0x-i2c add i2c_device_id + +Add i2c_device_id table for the vl53l0x-i2c driver, +helps in device instantiation using i2c_new_client_device() +or from userspace in cases where device-tree based description +is not possible now, like device(s) on a gbphy i2c adapter +created by greybus. + +Signed-off-by: Vaishnav M A + +--- + v4: + -update commit message, add punctuation + v3: + -modify commit message for readability + as suggested by Jonathan Cameron + v2: + -fix commit message + drivers/iio/proximity/vl53l0x-i2c.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c +index 5fbda9475ba9..7c29d4cae24a 100644 +--- a/drivers/iio/proximity/vl53l0x-i2c.c ++++ b/drivers/iio/proximity/vl53l0x-i2c.c +@@ -143,6 +143,12 @@ static int vl53l0x_probe(struct i2c_client *client) + return devm_iio_device_register(&client->dev, indio_dev); + } + ++static const struct i2c_device_id vl53l0x_id[] = { ++ { "vl53l0x", 0}, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, vl53l0x_id); ++ + static const struct of_device_id st_vl53l0x_dt_match[] = { + { .compatible = "st,vl53l0x", }, + { } +@@ -155,6 +161,7 @@ static struct i2c_driver vl53l0x_driver = { + .of_match_table = st_vl53l0x_dt_match, + }, + .probe_new = vl53l0x_probe, ++ .id_table = vl53l0x_id, + }; + module_i2c_driver(vl53l0x_driver); + +-- +2.25.1 + diff --git a/patches/drivers/mikrobus/0001-RFC-mikroBUS-driver-for-add-on-boards.patch b/patches/drivers/mikrobus/0001-mikrobus-driver-update-patch.patch similarity index 89% rename from patches/drivers/mikrobus/0001-RFC-mikroBUS-driver-for-add-on-boards.patch rename to patches/drivers/mikrobus/0001-mikrobus-driver-update-patch.patch index b3aa84b006..dac54db778 100644 --- a/patches/drivers/mikrobus/0001-RFC-mikroBUS-driver-for-add-on-boards.patch +++ b/patches/drivers/mikrobus/0001-mikrobus-driver-update-patch.patch @@ -1,54 +1,48 @@ -From e4ab599755fdaf0b76e418013ce6bf2ad2e9ff56 Mon Sep 17 00:00:00 2001 +From 3d0959e5ebaa1d082bf9ba2e5a4d86054c266d64 Mon Sep 17 00:00:00 2001 From: Vaishnav M A -Date: Mon, 20 Jul 2020 17:41:57 +0000 -Subject: [RFC PATCH v2] RFC : mikroBUS driver for add-on boards +Date: Thu, 15 Oct 2020 17:05:50 +0530 +Subject: [PATCH] mikrobus driver update patch + +This Patch series is an update to the mikroBUS driver +with support for serdev devices and fixed regulator. + +RFC v1 Patch : https://lkml.org/lkml/2020/7/24/518 . +The mikrobus driver is updated to add mikrobus ports from device-tree +overlays, the debug interfaces for adding mikrobus ports through sysFS +is removed, and the driver considers the extended usage of mikrobus +port pins from their standard purposes. change log: -- v2: remove debug interfaces for adding and deleting mikrobus - ports, add mikrobus ports via device-tree, handle pinmux, consider - extended usage of mikrobus pins from normal configuration + v2: support for adding mikroBUS ports from DT overlays, + remove debug sysFS interface for adding mikrobus ports, + consider extended pin usage/deviations from mikrobus standard + specifications, + use greybus CPort protocol enum instead of new protcol enums + Fix cases of wrong indendation, ignoring return values, freeing + allocated resources in case of errors and other style suggestions + in v1 review. Signed-off-by: Vaishnav M A --- - MAINTAINERS | 6 + drivers/misc/Kconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/mikrobus/Kconfig | 16 + - drivers/misc/mikrobus/Makefile | 7 + - drivers/misc/mikrobus/mikrobus_core.c | 694 ++++++++++++++++++++++ - drivers/misc/mikrobus/mikrobus_core.h | 190 ++++++ - drivers/misc/mikrobus/mikrobus_manifest.c | 440 ++++++++++++++ + drivers/misc/mikrobus/Makefile | 5 + + drivers/misc/mikrobus/mikrobus_core.c | 880 ++++++++++++++++++++++ + drivers/misc/mikrobus/mikrobus_core.h | 197 +++++ + drivers/misc/mikrobus/mikrobus_manifest.c | 475 ++++++++++++ drivers/misc/mikrobus/mikrobus_manifest.h | 20 + - drivers/misc/mikrobus/mikrobus_port.c | 179 ++++++ - include/linux/greybus/greybus_manifest.h | 47 ++ - 11 files changed, 1601 insertions(+) + include/linux/greybus/greybus_manifest.h | 49 ++ + 9 files changed, 1644 insertions(+) create mode 100644 drivers/misc/mikrobus/Kconfig create mode 100644 drivers/misc/mikrobus/Makefile create mode 100644 drivers/misc/mikrobus/mikrobus_core.c create mode 100644 drivers/misc/mikrobus/mikrobus_core.h create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.c create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.h - create mode 100644 drivers/misc/mikrobus/mikrobus_port.c -diff --git a/MAINTAINERS b/MAINTAINERS -index d53db30d1365..9a049746203f 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -11402,6 +11402,12 @@ M: Oliver Neukum - S: Maintained - F: drivers/usb/image/microtek.* - -+MIKROBUS ADDON BOARD DRIVER -+M: Vaishnav M A -+S: Maintained -+W: https://elinux.org/Mikrobus -+F: drivers/misc/mikrobus/ -+ - MIPS - M: Thomas Bogendoerfer - L: linux-mips@vger.kernel.org diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index e1b1ba5e2b92..334f0c39d56b 100644 +index ce136d685d14..cb1539f39b30 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -472,4 +472,5 @@ source "drivers/misc/ocxl/Kconfig" @@ -93,24 +87,22 @@ index 000000000000..5f42bc4e9410 + will be called mikrobus.ko diff --git a/drivers/misc/mikrobus/Makefile b/drivers/misc/mikrobus/Makefile new file mode 100644 -index 000000000000..af7256510310 +index 000000000000..982bdec90c09 --- /dev/null +++ b/drivers/misc/mikrobus/Makefile -@@ -0,0 +1,7 @@ +@@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# mikroBUS Core + -+mikrobus-y := mikrobus_core.o mikrobus_manifest.o -+mikrobus_port-y := mikrobus_port.o +obj-$(CONFIG_MIKROBUS) += mikrobus.o -+obj-$(CONFIG_MIKROBUS) += mikrobus_port.o ++mikrobus-y := mikrobus_core.o mikrobus_manifest.o \ No newline at end of file diff --git a/drivers/misc/mikrobus/mikrobus_core.c b/drivers/misc/mikrobus/mikrobus_core.c new file mode 100644 -index 000000000000..f1ccd4b4d5a2 +index 000000000000..7e342e2b079b --- /dev/null +++ b/drivers/misc/mikrobus/mikrobus_core.c -@@ -0,0 +1,694 @@ +@@ -0,0 +1,880 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mikroBUS driver for instantiating add-on @@ -145,6 +137,9 @@ index 000000000000..f1ccd4b4d5a2 +#include +#include +#include ++#include ++#include ++#include +#include + +#include "mikrobus_core.h" @@ -490,11 +485,14 @@ index 000000000000..f1ccd4b4d5a2 + struct board_device_info *dev, char *board_name) +{ + struct i2c_board_info *i2c; -+ struct spi_board_info *spi; ++ struct spi_device *spi; ++ struct serdev_device *serdev; + struct platform_device *pdev; + struct gpiod_lookup_table *lookup; ++ struct regulator_consumer_supply regulator; + char devname[MIKROBUS_NAME_SIZE]; + int i; ++ u64 *val; + + dev_info(&port->dev, "registering device : %s", dev->drv_name); + @@ -520,24 +518,54 @@ index 000000000000..f1ccd4b4d5a2 + lookup->table[i].chip_hwnum = + mikrobus_gpio_hwnum_get(port, + lookup->table[i].chip_hwnum); -+ lookup->table[i].flags = GPIO_ACTIVE_HIGH; + } + gpiod_add_lookup_table(lookup); + } ++ if (dev->regulators) { ++ if (dev->protocol == GREYBUS_PROTOCOL_SPI) { ++ snprintf(devname, sizeof(devname), "%s.%u", ++ dev_name(&port->spi_mstr->dev), ++ port->chip_select[dev->reg]); ++ regulator.dev_name = kmemdup(devname, MIKROBUS_NAME_SIZE, GFP_KERNEL); ++ } else if (dev->protocol == GREYBUS_PROTOCOL_RAW) { ++ snprintf(devname, sizeof(devname), "%s.%u", ++ dev->drv_name, dev->reg); ++ regulator.dev_name = kmemdup(devname, MIKROBUS_NAME_SIZE, GFP_KERNEL); ++ } else ++ regulator.dev_name = dev->drv_name; ++ ++ for (i = 0; i < dev->num_regulators; i++) { ++ val = dev->regulators[i].value.u64_data; ++ regulator.supply = kmemdup(dev->regulators[i].name, MIKROBUS_NAME_SIZE, GFP_KERNEL); ++ dev_info(&port->dev, " adding fixed regulator %llu uv, %s for %s\n", ++ *val, regulator.supply, regulator.dev_name); ++ regulator_register_always_on(0, dev->regulators[i].name, ®ulator, ++ 1, *val); ++ } ++ } + switch (dev->protocol) { + case GREYBUS_PROTOCOL_SPI: -+ spi = kzalloc(sizeof(*spi), GFP_KERNEL); ++ spi = spi_alloc_device(port->spi_mstr); + if (!spi) + return -ENOMEM; + strncpy(spi->modalias, dev->drv_name, sizeof(spi->modalias) - 1); + if (dev->irq) + spi->irq = mikrobus_irq_get(port, dev->irq, dev->irq_type); + if (dev->properties) -+ spi->properties = dev->properties; ++ device_add_properties(&spi->dev, dev->properties); + spi->chip_select = port->chip_select[dev->reg]; + spi->max_speed_hz = dev->max_speed_hz; + spi->mode = dev->mode; -+ dev->dev_client = (void *) spi_new_device(port->spi_mstr, spi); ++ if (dev->clocks) { ++ for (i = 0; i < dev->num_clocks; i++) { ++ val = dev->clocks[i].value.u64_data; ++ dev_info(&port->dev, " adding fixed clock %s, %llu hz\n", ++ dev->clocks[i].name, *val); ++ //failing: under debug ++ clk_register_fixed_rate(&spi->dev, dev->clocks[i].name, devname, 0, *val); ++ } ++ } ++ dev->dev_client = (void *) spi_add_device(spi); + break; + case GREYBUS_PROTOCOL_I2C: + i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); @@ -561,7 +589,15 @@ index 000000000000..f1ccd4b4d5a2 + platform_device_add(dev->dev_client); + break; + case GREYBUS_PROTOCOL_UART: -+ dev_info(&port->dev, "serdev devices support not yet added"); ++ serdev = serdev_device_alloc(port->ser_ctrl); ++ if (!serdev) ++ return -ENOMEM; ++ strncpy(serdev->modalias, dev->drv_name, sizeof(serdev->modalias) - 1); ++ if (dev->properties) ++ device_add_properties(&serdev->dev, dev->properties); ++ dev->dev_client = serdev; ++ serdev_device_add(serdev); ++ break; + break; + default: + return -EINVAL; @@ -589,7 +625,7 @@ index 000000000000..f1ccd4b4d5a2 + platform_device_unregister((struct platform_device *)dev->dev_client); + break; + case GREYBUS_PROTOCOL_UART: -+ dev_err(&port->dev, "serdev devices support not yet added"); ++ serdev_device_remove((struct serdev_device *)dev->dev_client); + break; + } +} @@ -764,6 +800,144 @@ index 000000000000..f1ccd4b4d5a2 +} +EXPORT_SYMBOL_GPL(mikrobus_port_delete); + ++static int mikrobus_port_probe_pinctrl_setup(struct mikrobus_port *port) ++{ ++ struct pinctrl_state *state; ++ struct device *dev = port->dev.parent; ++ int retval, i; ++ ++ state = pinctrl_lookup_state(port->pinctrl, PINCTRL_STATE_DEFAULT); ++ if (!IS_ERR(state)) { ++ retval = pinctrl_select_state(port->pinctrl, state); ++ if (retval != 0) { ++ dev_err(dev, "Failed to select state %s\n", ++ PINCTRL_STATE_DEFAULT); ++ return retval; ++ } ++ } else { ++ dev_err(dev, "failed to find state %s\n", ++ PINCTRL_STATE_DEFAULT); ++ return PTR_ERR(state); ++ } ++ ++ for (i = 0; i < MIKROBUS_NUM_PINCTRL_STATE; i++) { ++ port->pinctrl_selected[i] = ++ kmalloc(MIKROBUS_PINCTRL_NAME_SIZE, GFP_KERNEL); ++ sprintf(port->pinctrl_selected[i], "%s_%s", ++ MIKROBUS_PINCTRL_STR[i], PINCTRL_STATE_DEFAULT); ++ } ++ ++ retval = mikrobus_port_pinctrl_select(port); ++ if (retval) ++ dev_err(dev, "failed to select pinctrl states [%d]", retval); ++ return retval; ++} ++ ++static int mikrobus_port_probe(struct platform_device *pdev) ++{ ++ struct mikrobus_port *port; ++ struct device *dev = &pdev->dev; ++ struct device_node *i2c_adap_np; ++ struct device_node *uart_np; ++ int retval; ++ u32 val; ++ ++ port = kzalloc(sizeof(*port), GFP_KERNEL); ++ if (!port) ++ return -ENOMEM; ++ ++ i2c_adap_np = of_parse_phandle(dev->of_node, "i2c-adapter", 0); ++ if (!i2c_adap_np) { ++ dev_err(dev, "cannot parse i2c-adapter\n"); ++ retval = -ENODEV; ++ goto err_port; ++ } ++ port->i2c_adap = of_find_i2c_adapter_by_node(i2c_adap_np); ++ of_node_put(i2c_adap_np); ++ retval = device_property_read_u32(dev, "spi-master", &val); ++ if (retval) { ++ dev_err(dev, "failed to get spi-master [%d]\n", retval); ++ goto err_port; ++ } ++ port->spi_mstr = spi_busnum_to_master(val); ++ retval = device_property_read_u32_array(dev, "spi-cs", ++ port->chip_select, 2); ++ if (retval) { ++ dev_err(dev, "failed to get spi-cs [%d]\n", retval); ++ goto err_port; ++ } ++ uart_np = of_parse_phandle(dev->of_node, "uart", 0); ++ if (!uart_np) { ++ dev_err(dev, "cannot parse uart\n"); ++ retval = -ENODEV; ++ goto err_port; ++ } ++ port->ser_ctrl = of_find_serdev_controller_by_node(uart_np); ++ of_node_put(uart_np); ++ //port->pwm = devm_pwm_get(dev, NULL); ++ //if (IS_ERR(port->pwm)) { ++ // retval = PTR_ERR(port->pwm); ++ // if (retval != -EPROBE_DEFER) ++ // dev_err(dev, "failed to request PWM device [%d]\n", ++ // retval); ++ // goto err_port; ++ //} ++ port->gpios = gpiod_get_array(dev, "mikrobus", GPIOD_OUT_LOW); ++ if (IS_ERR(port->gpios)) { ++ retval = PTR_ERR(port->gpios); ++ dev_err(dev, "failed to get gpio array [%d]\n", retval); ++ goto err_port; ++ } ++ port->pinctrl = devm_pinctrl_get(dev); ++ if (IS_ERR(port->pinctrl)) { ++ retval = PTR_ERR(port->pinctrl); ++ dev_err(dev, "failed to get pinctrl [%d]\n", retval); ++ goto err_port; ++ } ++ port->dev.parent = dev; ++ port->dev.of_node = pdev->dev.of_node; ++ ++ retval = mikrobus_port_probe_pinctrl_setup(port); ++ if (retval) { ++ dev_err(dev, "failed to setup pinctrl [%d]\n", retval); ++ goto err_port; ++ } ++ ++ retval = mikrobus_port_register(port); ++ if (retval) { ++ pr_err("port : can't register port [%d]\n", retval); ++ goto err_port; ++ } ++ platform_set_drvdata(pdev, port); ++ return 0; ++err_port: ++ kfree(port); ++ return retval; ++} ++ ++static int mikrobus_port_remove(struct platform_device *pdev) ++{ ++ struct mikrobus_port *port = platform_get_drvdata(pdev); ++ ++ mikrobus_port_delete(port); ++ return 0; ++} ++ ++static const struct of_device_id mikrobus_port_of_match[] = { ++ {.compatible = "linux,mikrobus"}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, mikrobus_port_of_match); ++ ++static struct platform_driver mikrobus_port_driver = { ++ .probe = mikrobus_port_probe, ++ .remove = mikrobus_port_remove, ++ .driver = { ++ .name = "mikrobus", ++ .of_match_table = of_match_ptr(mikrobus_port_of_match), ++ }, ++}; ++ +static int __init mikrobus_init(void) +{ + int retval; @@ -784,7 +958,10 @@ index 000000000000..f1ccd4b4d5a2 + __mikrobus_first_dynamic_bus_num = retval + 1; + + is_registered = true; -+ return 0; ++ retval = platform_driver_register(&mikrobus_port_driver); ++ if (retval) ++ pr_err("driver register failed [%d]\n", retval); ++ return retval; + +class_err: + bus_unregister(&mikrobus_bus_type); @@ -796,6 +973,7 @@ index 000000000000..f1ccd4b4d5a2 + +static void __exit mikrobus_exit(void) +{ ++ platform_driver_unregister(&mikrobus_port_driver); + bus_unregister(&mikrobus_bus_type); + class_compat_unregister(mikrobus_port_compat_class); + idr_destroy(&mikrobus_port_idr); @@ -807,10 +985,10 @@ index 000000000000..f1ccd4b4d5a2 +MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mikrobus/mikrobus_core.h b/drivers/misc/mikrobus/mikrobus_core.h new file mode 100644 -index 000000000000..03894ad6d48f +index 000000000000..9ac1e6248018 --- /dev/null +++ b/drivers/misc/mikrobus/mikrobus_core.h -@@ -0,0 +1,190 @@ +@@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mikroBUS Driver for instantiating add-on @@ -859,12 +1037,14 @@ index 000000000000..03894ad6d48f + +enum mikrobus_property_type { + MIKROBUS_PROPERTY_TYPE_MIKROBUS = 0x00, -+ MIKROBUS_PROPERTY_TYPE_LINK = 0x01, ++ MIKROBUS_PROPERTY_TYPE_PROPERTY = 0x01, + MIKROBUS_PROPERTY_TYPE_GPIO = 0x02, + MIKROBUS_PROPERTY_TYPE_U8 = 0x03, + MIKROBUS_PROPERTY_TYPE_U16 = 0x04, + MIKROBUS_PROPERTY_TYPE_U32 = 0x05, + MIKROBUS_PROPERTY_TYPE_U64 = 0x06, ++ MIKROBUS_PROPERTY_TYPE_REGULATOR = 0x07, ++ MIKROBUS_PROPERTY_TYPE_CLOCK = 0x08, +}; + +enum mikrobus_pin { @@ -924,9 +1104,13 @@ index 000000000000..03894ad6d48f +struct board_device_info { + struct gpiod_lookup_table *gpio_lookup; + struct property_entry *properties; ++ struct property_entry *regulators; ++ struct property_entry *clocks; + struct list_head links; + unsigned short num_gpio_resources; + unsigned short num_properties; ++ unsigned short num_regulators; ++ unsigned short num_clocks; + unsigned short protocol; + unsigned short reg; + unsigned int mode; @@ -979,6 +1163,7 @@ index 000000000000..03894ad6d48f + struct addon_board_info *board; + struct i2c_adapter *i2c_adap; + struct spi_master *spi_mstr; ++ struct serdev_controller *ser_ctrl; + struct nvmem_device *eeprom; + struct gpio_descs *gpios; + struct pwm_device *pwm; @@ -1003,10 +1188,10 @@ index 000000000000..03894ad6d48f +#endif /* __MIKROBUS_H */ diff --git a/drivers/misc/mikrobus/mikrobus_manifest.c b/drivers/misc/mikrobus/mikrobus_manifest.c new file mode 100644 -index 000000000000..629720b4c0fa +index 000000000000..9cacc3d36d4e --- /dev/null +++ b/drivers/misc/mikrobus/mikrobus_manifest.c -@@ -0,0 +1,440 @@ +@@ -0,0 +1,475 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mikroBUS manifest parsing, an @@ -1276,8 +1461,12 @@ index 000000000000..629720b4c0fa + val_u8 = kmemdup(&desc_property->value, desc_property->length, GFP_KERNEL); + if (prop_type == MIKROBUS_PROPERTY_TYPE_GPIO) + board_dev->num_gpio_resources = desc_property->length; -+ else if (prop_type == MIKROBUS_PROPERTY_TYPE_LINK) ++ else if (prop_type == MIKROBUS_PROPERTY_TYPE_PROPERTY) + board_dev->num_properties = desc_property->length; ++ else if (prop_type == MIKROBUS_PROPERTY_TYPE_REGULATOR) ++ board_dev->num_regulators = desc_property->length; ++ else if (prop_type == MIKROBUS_PROPERTY_TYPE_CLOCK) ++ board_dev->num_clocks = desc_property->length; + return val_u8; +} + @@ -1290,6 +1479,9 @@ index 000000000000..629720b4c0fa + struct manifest_desc *descriptor; + u8 *gpio_desc_link; + u8 *prop_link; ++ u8 *reg_link; ++ u8 *clock_link; ++ u8 *gpioval; + int retval; + int i; + @@ -1312,7 +1504,7 @@ index 000000000000..629720b4c0fa + + if (dev_desc->prop_link > 0) { + prop_link = mikrobus_property_link_get(board, dev_desc->prop_link, -+ board_dev, MIKROBUS_PROPERTY_TYPE_LINK); ++ board_dev, MIKROBUS_PROPERTY_TYPE_PROPERTY); + if (!prop_link) { + retval = -ENOENT; + goto err_free_board_dev; @@ -1344,7 +1536,9 @@ index 000000000000..629720b4c0fa + continue; + desc_property = descriptor->data; + if (desc_property->id == gpio_desc_link[i]) { -+ lookup->table[i].chip_hwnum = *desc_property->value; ++ gpioval = desc_property->value; ++ lookup->table[i].chip_hwnum = gpioval[0]; ++ lookup->table[i].flags = gpioval[1]; + lookup->table[i].con_id = + mikrobus_string_get(board, + desc_property->propname_stringid); @@ -1354,6 +1548,32 @@ index 000000000000..629720b4c0fa + } + board_dev->gpio_lookup = lookup; + } ++ ++ if (dev_desc->reg_link > 0) { ++ reg_link = mikrobus_property_link_get(board, dev_desc->reg_link, ++ board_dev, MIKROBUS_PROPERTY_TYPE_REGULATOR); ++ if (!reg_link) { ++ retval = -ENOENT; ++ goto err_free_board_dev; ++ } ++ pr_info("device %d, number of regulators=%d", board_dev->id, ++ board_dev->num_regulators); ++ board_dev->regulators = mikrobus_property_entry_get(board, reg_link, ++ board_dev->num_regulators); ++ } ++ ++ if (dev_desc->clock_link > 0) { ++ clock_link = mikrobus_property_link_get(board, dev_desc->clock_link, ++ board_dev, MIKROBUS_PROPERTY_TYPE_CLOCK); ++ if (!clock_link) { ++ retval = -ENOENT; ++ goto err_free_board_dev; ++ } ++ pr_info("device %d, number of clocks=%d", board_dev->id, ++ board_dev->num_clocks); ++ board_dev->clocks = mikrobus_property_entry_get(board, clock_link, ++ board_dev->num_clocks); ++ } + list_add_tail(&board_dev->links, &board->devices); + return 0; +err_free_board_dev: @@ -1398,7 +1618,7 @@ index 000000000000..629720b4c0fa + manifest_size = le16_to_cpu(header->size); + + if (manifest_size != size) { -+ pr_err("invalid manifest size(%zu < %zu)", size, manifest_size); ++ pr_err("invalid manifest size(%zu < %u)", size, manifest_size); + return -EINVAL; + } + @@ -1414,7 +1634,7 @@ index 000000000000..629720b4c0fa + while (size) { + desc_size = board_descriptor_add(board, desc, size); + if (desc_size < 0) { -+ pr_err("invalid manifest descriptor, size: %zu", desc_size); ++ pr_err("invalid manifest descriptor, size: %u", desc_size); + return -EINVAL; + } + desc = (void *)desc + desc_size; @@ -1473,193 +1693,8 @@ index 000000000000..36b64b2093f5 +size_t mikrobus_manifest_header_validate(void *data, size_t size); + +#endif /* __MIKROBUS_MANIFEST_H */ -diff --git a/drivers/misc/mikrobus/mikrobus_port.c b/drivers/misc/mikrobus/mikrobus_port.c -new file mode 100644 -index 000000000000..d54520b98053 ---- /dev/null -+++ b/drivers/misc/mikrobus/mikrobus_port.c -@@ -0,0 +1,179 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * mikroBUS driver for adding mikrobus port from device tree -+ * -+ * Copyright 2020 Vaishnav M A, BeagleBoard.org Foundation. -+ */ -+#define pr_fmt(fmt) "mikrobus_port:%s: " fmt, __func__ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mikrobus_core.h" -+ -+static int mikrobus_port_probe_pinctrl_setup(struct mikrobus_port *port) -+{ -+ struct pinctrl_state *state; -+ struct device *dev = port->dev.parent; -+ int retval, i; -+ -+ state = pinctrl_lookup_state(port->pinctrl, PINCTRL_STATE_DEFAULT); -+ if (!IS_ERR(state)) { -+ retval = pinctrl_select_state(port->pinctrl, state); -+ if (retval != 0) { -+ dev_err(dev, "Failed to select state %s\n", -+ PINCTRL_STATE_DEFAULT); -+ return retval; -+ } -+ } else { -+ dev_err(dev, "failed to find state %s\n", -+ PINCTRL_STATE_DEFAULT); -+ return PTR_ERR(state); -+ } -+ -+ for (i = 0; i < MIKROBUS_NUM_PINCTRL_STATE; i++) { -+ port->pinctrl_selected[i] = -+ kmalloc(MIKROBUS_PINCTRL_NAME_SIZE, GFP_KERNEL); -+ sprintf(port->pinctrl_selected[i], "%s_%s", -+ MIKROBUS_PINCTRL_STR[i], PINCTRL_STATE_DEFAULT); -+ } -+ -+ retval = mikrobus_port_pinctrl_select(port); -+ if (retval) -+ dev_err(dev, "failed to select pinctrl states [%d]", retval); -+ return retval; -+} -+ -+static int mikrobus_port_probe(struct platform_device *pdev) -+{ -+ struct mikrobus_port *port; -+ struct device *dev = &pdev->dev; -+ struct device_node *i2c_adap_np; -+ int retval; -+ u32 val; -+ -+ port = kzalloc(sizeof(*port), GFP_KERNEL); -+ if (!port) -+ return -ENOMEM; -+ -+ i2c_adap_np = of_parse_phandle(dev->of_node, "i2c-adapter", 0); -+ if (!i2c_adap_np) { -+ dev_err(dev, "cannot parse i2c-adapter\n"); -+ retval = -ENODEV; -+ goto err_port; -+ } -+ port->i2c_adap = of_find_i2c_adapter_by_node(i2c_adap_np); -+ of_node_put(i2c_adap_np); -+ retval = device_property_read_u32(dev, "spi-master", &val); -+ if (retval) { -+ dev_err(dev, "failed to get spi-master [%d]\n", retval); -+ goto err_port; -+ } -+ port->spi_mstr = spi_busnum_to_master(val); -+ retval = device_property_read_u32_array(dev, "spi-cs", -+ port->chip_select, 2); -+ if (retval) { -+ dev_err(dev, "failed to get spi-cs [%d]\n", retval); -+ goto err_port; -+ } -+ //port->pwm = devm_pwm_get(dev, NULL); -+ //if (IS_ERR(port->pwm)) { -+ // retval = PTR_ERR(port->pwm); -+ // if (retval != -EPROBE_DEFER) -+ // dev_err(dev, "failed to request PWM device [%d]\n", -+ // retval); -+ // goto err_port; -+ //} -+ port->gpios = gpiod_get_array(dev, "mikrobus", GPIOD_OUT_LOW); -+ if (IS_ERR(port->gpios)) { -+ retval = PTR_ERR(port->gpios); -+ dev_err(dev, "failed to get gpio array [%d]\n", retval); -+ goto err_port; -+ } -+ port->pinctrl = devm_pinctrl_get(dev); -+ if (IS_ERR(port->pinctrl)) { -+ retval = PTR_ERR(port->pinctrl); -+ dev_err(dev, "failed to get pinctrl [%d]\n", retval); -+ goto err_port; -+ } -+ port->dev.parent = dev; -+ port->dev.of_node = pdev->dev.of_node; -+ -+ retval = mikrobus_port_probe_pinctrl_setup(port); -+ if (retval) { -+ dev_err(dev, "failed to setup pinctrl [%d]\n", retval); -+ goto err_port; -+ } -+ -+ retval = mikrobus_port_register(port); -+ if (retval) { -+ pr_err("port : can't register port [%d]\n", retval); -+ goto err_port; -+ } -+ platform_set_drvdata(pdev, port); -+ return 0; -+err_port: -+ kfree(port); -+ return retval; -+} -+ -+static int mikrobus_port_remove(struct platform_device *pdev) -+{ -+ struct mikrobus_port *port = platform_get_drvdata(pdev); -+ -+ mikrobus_port_delete(port); -+ return 0; -+} -+ -+static const struct of_device_id mikrobus_port_of_match[] = { -+ {.compatible = "linux,mikrobus"}, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mikrobus_port_of_match); -+ -+static struct platform_driver mikrobus_port_driver = { -+ .probe = mikrobus_port_probe, -+ .remove = mikrobus_port_remove, -+ .driver = { -+ .name = "mikrobus", -+ .of_match_table = of_match_ptr(mikrobus_port_of_match), -+ }, -+}; -+ -+static int __init -+mikrobus_port_init_driver(void) -+{ -+ int retval; -+ -+ retval = platform_driver_register(&mikrobus_port_driver); -+ if (retval) -+ pr_err("driver register failed [%d]\n", retval); -+ return retval; -+} -+subsys_initcall(mikrobus_port_init_driver); -+ -+static void __exit mikrobus_port_exit_driver(void) -+{ -+ platform_driver_unregister(&mikrobus_port_driver); -+} -+module_exit(mikrobus_port_exit_driver); -+ -+MODULE_AUTHOR("Vaishnav M A "); -+MODULE_DESCRIPTION("mikroBUS port module"); -+MODULE_LICENSE("GPL"); diff --git a/include/linux/greybus/greybus_manifest.h b/include/linux/greybus/greybus_manifest.h -index 6e62fe478712..821661ea7f01 100644 +index 6e62fe478712..50d5a5fd3d51 100644 --- a/include/linux/greybus/greybus_manifest.h +++ b/include/linux/greybus/greybus_manifest.h @@ -23,6 +23,9 @@ enum greybus_descriptor_type { @@ -1672,7 +1707,7 @@ index 6e62fe478712..821661ea7f01 100644 }; enum greybus_protocol { -@@ -151,6 +154,47 @@ struct greybus_descriptor_cport { +@@ -151,6 +154,49 @@ struct greybus_descriptor_cport { __u8 protocol_id; /* enum greybus_protocol */ } __packed; @@ -1714,13 +1749,15 @@ index 6e62fe478712..821661ea7f01 100644 + __u8 mode; + __u8 prop_link; + __u8 gpio_link; -+ __u8 pad[3]; ++ __u8 reg_link; ++ __u8 clock_link; ++ __u8 pad[1]; +} __packed; + struct greybus_descriptor_header { __le16 size; __u8 type; /* enum greybus_descriptor_type */ -@@ -164,6 +208,9 @@ struct greybus_descriptor { +@@ -164,6 +210,9 @@ struct greybus_descriptor { struct greybus_descriptor_interface interface; struct greybus_descriptor_bundle bundle; struct greybus_descriptor_cport cport; diff --git a/patches/drivers/mikrobus/0002-mikroBUS-build-fixes.patch b/patches/drivers/mikrobus/0002-mikroBUS-build-fixes.patch deleted file mode 100644 index 147e748ef5..0000000000 --- a/patches/drivers/mikrobus/0002-mikroBUS-build-fixes.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 1717cc66205b1df9d01fec4410b66e448f0a45ea Mon Sep 17 00:00:00 2001 -From: Jason Kridner -Date: Thu, 27 Aug 2020 02:00:14 -0400 -Subject: [PATCH] mikroBUS build fixes - ---- - drivers/misc/mikrobus/Makefile | 5 ++--- - drivers/misc/mikrobus/mikrobus_core.c | 2 ++ - drivers/misc/mikrobus/mikrobus_manifest.c | 4 ++-- - 3 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/drivers/misc/mikrobus/Makefile b/drivers/misc/mikrobus/Makefile -index af7256510310..05a6ec3a013d 100644 ---- a/drivers/misc/mikrobus/Makefile -+++ b/drivers/misc/mikrobus/Makefile -@@ -1,7 +1,6 @@ - # SPDX-License-Identifier: GPL-2.0 - # mikroBUS Core - --mikrobus-y := mikrobus_core.o mikrobus_manifest.o --mikrobus_port-y := mikrobus_port.o - obj-$(CONFIG_MIKROBUS) += mikrobus.o --obj-$(CONFIG_MIKROBUS) += mikrobus_port.o -\ No newline at end of file -+obj-$(CONFIG_MIKROBUS) += mikrobus_port.o -+mikrobus-y := mikrobus_core.o mikrobus_manifest.o -diff --git a/drivers/misc/mikrobus/mikrobus_core.c b/drivers/misc/mikrobus/mikrobus_core.c -index f1ccd4b4d5a2..7ac51c74d0fb 100644 ---- a/drivers/misc/mikrobus/mikrobus_core.c -+++ b/drivers/misc/mikrobus/mikrobus_core.c -@@ -689,6 +689,8 @@ static void __exit mikrobus_exit(void) - } - module_exit(mikrobus_exit); - -+EXPORT_SYMBOL(MIKROBUS_PINCTRL_STR); -+ - MODULE_AUTHOR("Vaishnav M A "); - MODULE_DESCRIPTION("mikroBUS main module"); - MODULE_LICENSE("GPL v2"); -diff --git a/drivers/misc/mikrobus/mikrobus_manifest.c b/drivers/misc/mikrobus/mikrobus_manifest.c -index 629720b4c0fa..077d61e006b0 100644 ---- a/drivers/misc/mikrobus/mikrobus_manifest.c -+++ b/drivers/misc/mikrobus/mikrobus_manifest.c -@@ -389,7 +389,7 @@ int mikrobus_manifest_parse(struct addon_board_info *board, void *data, - manifest_size = le16_to_cpu(header->size); - - if (manifest_size != size) { -- pr_err("invalid manifest size(%zu < %zu)", size, manifest_size); -+ pr_err("invalid manifest size(%zu < %u)", size, manifest_size); - return -EINVAL; - } - -@@ -405,7 +405,7 @@ int mikrobus_manifest_parse(struct addon_board_info *board, void *data, - while (size) { - desc_size = board_descriptor_add(board, desc, size); - if (desc_size < 0) { -- pr_err("invalid manifest descriptor, size: %zu", desc_size); -+ pr_err("invalid manifest descriptor, size: %u", desc_size); - return -EINVAL; - } - desc = (void *)desc + desc_size; --- -2.17.1 - diff --git a/patches/drivers/serdev/0001-serdev-Add-serdev_device_id.patch b/patches/drivers/serdev/0001-serdev-Add-serdev_device_id.patch new file mode 100644 index 0000000000..5c7433e990 --- /dev/null +++ b/patches/drivers/serdev/0001-serdev-Add-serdev_device_id.patch @@ -0,0 +1,159 @@ +From e52e4ccf1de73e51ac5fc27989f376c9725f9582 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda Delgado +Date: Sun, 18 Oct 2020 05:26:39 +0530 +Subject: [RFC PATCH 1/5] serdev: Add serdev_device_id + +Currently,a serdev device driver can only be used with devices that are +nodes of a device tree, or are part of the ACPI table.id_table will be +used for devices that are not part of the device tree nor the ACPI table +(example: device on greybus gbphy created uart). + +corresponding modalias field is introduced to name the driver to be +used with the device, required device(s) that are neither described +by device tree nor ACPI table. + +serdev_device_uevent is also extended for modalias devices. + +Signed-off-by: Ricardo Ribalda Delgado +--- + drivers/tty/serdev/core.c | 41 ++++++++++++++++++++++++++++----- + include/linux/mod_devicetable.h | 10 ++++++++ + include/linux/serdev.h | 3 +++ + 3 files changed, 48 insertions(+), 6 deletions(-) + +diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c +index c5f0d936b003..01b248fdc264 100644 +--- a/drivers/tty/serdev/core.c ++++ b/drivers/tty/serdev/core.c +@@ -27,12 +27,17 @@ static ssize_t modalias_show(struct device *dev, + struct device_attribute *attr, char *buf) + { + int len; ++ struct serdev_device *serdev = to_serdev_device(dev); + + len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1); + if (len != -ENODEV) + return len; + +- return of_device_modalias(dev, buf, PAGE_SIZE); ++ len = of_device_modalias(dev, buf, PAGE_SIZE); ++ if (len != -ENODEV) ++ return len; ++ ++ return sprintf(buf, "%s%s\n", SERDEV_MODULE_PREFIX, serdev->modalias); + } + static DEVICE_ATTR_RO(modalias); + +@@ -45,14 +50,18 @@ ATTRIBUTE_GROUPS(serdev_device); + static int serdev_device_uevent(struct device *dev, struct kobj_uevent_env *env) + { + int rc; +- +- /* TODO: platform modalias */ ++ struct serdev_device *serdev = to_serdev_device(dev); + + rc = acpi_device_uevent_modalias(dev, env); + if (rc != -ENODEV) + return rc; + +- return of_device_uevent_modalias(dev, env); ++ rc = of_device_uevent_modalias(dev, env); ++ if (rc != -ENODEV) ++ return rc; ++ ++ return add_uevent_var(env, "MODALIAS=%s%s", SERDEV_MODULE_PREFIX, ++ serdev->modalias); + } + + static void serdev_device_release(struct device *dev) +@@ -83,16 +92,36 @@ static const struct device_type serdev_ctrl_type = { + .release = serdev_ctrl_release, + }; + ++static int serdev_match_id(const struct serdev_device_id *id, ++ const struct serdev_device *sdev) ++{ ++ while (id->name[0]) { ++ if (!strcmp(sdev->modalias, id->name)) ++ return 1; ++ id++; ++ } ++ ++ return 0; ++} ++ + static int serdev_device_match(struct device *dev, struct device_driver *drv) + { ++ const struct serdev_device *sdev = to_serdev_device(dev); ++ const struct serdev_device_driver *sdrv = to_serdev_device_driver(drv); ++ + if (!is_serdev_device(dev)) + return 0; + +- /* TODO: platform matching */ + if (acpi_driver_match_device(dev, drv)) + return 1; + +- return of_driver_match_device(dev, drv); ++ if (of_driver_match_device(dev, drv)) ++ return 1; ++ ++ if (sdrv->id_table) ++ return serdev_match_id(sdrv->id_table, sdev); ++ ++ return strcmp(sdev->modalias, drv->name) == 0; + } + + /** +diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h +index 5b08a473cdba..656353952da2 100644 +--- a/include/linux/mod_devicetable.h ++++ b/include/linux/mod_devicetable.h +@@ -486,6 +486,16 @@ struct i3c_device_id { + const void *data; + }; + ++/* serdev */ ++ ++#define SERDEV_NAME_SIZE 32 ++#define SERDEV_MODULE_PREFIX "serdev:" ++ ++struct serdev_device_id { ++ char name[SERDEV_NAME_SIZE]; ++ kernel_ulong_t driver_data; ++}; ++ + /* spi */ + + #define SPI_NAME_SIZE 32 +diff --git a/include/linux/serdev.h b/include/linux/serdev.h +index 9f14f9c12ec4..0d9c90a250b0 100644 +--- a/include/linux/serdev.h ++++ b/include/linux/serdev.h +@@ -7,6 +7,7 @@ + + #include + #include ++#include + #include + #include + +@@ -45,6 +46,7 @@ struct serdev_device { + const struct serdev_device_ops *ops; + struct completion write_comp; + struct mutex write_lock; ++ char modalias[SERDEV_NAME_SIZE]; + }; + + static inline struct serdev_device *to_serdev_device(struct device *d) +@@ -63,6 +65,7 @@ struct serdev_device_driver { + struct device_driver driver; + int (*probe)(struct serdev_device *); + void (*remove)(struct serdev_device *); ++ const struct serdev_device_id *id_table; + }; + + static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d) +-- +2.25.1 + diff --git a/patches/drivers/serdev/0002-file2alias-Support-for-serdev-devices.patch b/patches/drivers/serdev/0002-file2alias-Support-for-serdev-devices.patch new file mode 100644 index 0000000000..ce00ea7b0c --- /dev/null +++ b/patches/drivers/serdev/0002-file2alias-Support-for-serdev-devices.patch @@ -0,0 +1,70 @@ +From 68d7f278257a1f0dc7533ee17c3f9d5da2455bb7 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda Delgado +Date: Sun, 18 Oct 2020 05:46:10 +0530 +Subject: [RFC PATCH 2/5] file2alias: Support for serdev devices + +This patch allows file2alias to generate the proper module headers to +support serdev modalias drivers. + +Eg: + +root@qt5022:~# modinfo serdev:ttydev | grep alias +alias: serdev:ttydev_serdev +alias: serdev:ttydev + +root@qt5022:~# + cat /lib/modules/4.16.0-qtec-standard/modules.alias | grep serdev +alias serdev:ttydev_serdev serdev_ttydev +alias serdev:ttydev serdev_ttydev + +Signed-off-by: Ricardo Ribalda Delgado +--- + scripts/mod/devicetable-offsets.c | 3 +++ + scripts/mod/file2alias.c | 10 ++++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c +index 27007c18e754..732cd03e911d 100644 +--- a/scripts/mod/devicetable-offsets.c ++++ b/scripts/mod/devicetable-offsets.c +@@ -152,6 +152,9 @@ int main(void) + DEVID_FIELD(i3c_device_id, part_id); + DEVID_FIELD(i3c_device_id, extra_info); + ++ DEVID(serdev_device_id); ++ DEVID_FIELD(serdev_device_id, name); ++ + DEVID(spi_device_id); + DEVID_FIELD(spi_device_id, name); + +diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c +index 2417dd1dee33..540fee036d9d 100644 +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -947,6 +947,15 @@ static int do_spi_entry(const char *filename, void *symval, + return 1; + } + ++static int do_serdev_entry(const char *filename, void *symval, ++ char *alias) ++{ ++ DEF_FIELD_ADDR(symval, serdev_device_id, name); ++ sprintf(alias, SERDEV_MODULE_PREFIX "%s", *name); ++ ++ return 1; ++} ++ + static const struct dmifield { + const char *prefix; + int field; +@@ -1420,6 +1429,7 @@ static const struct devtable devtable[] = { + {"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry}, + {"i2c", SIZE_i2c_device_id, do_i2c_entry}, + {"i3c", SIZE_i3c_device_id, do_i3c_entry}, ++ {"serdev", SIZE_serdev_device_id, do_serdev_entry}, + {"spi", SIZE_spi_device_id, do_spi_entry}, + {"dmi", SIZE_dmi_system_id, do_dmi_entry}, + {"platform", SIZE_platform_device_id, do_platform_entry}, +-- +2.25.1 + diff --git a/patches/drivers/serdev/0003-serdev-add-of_-helper-to-get-serdev-controller.patch b/patches/drivers/serdev/0003-serdev-add-of_-helper-to-get-serdev-controller.patch new file mode 100644 index 0000000000..20f0dc86d3 --- /dev/null +++ b/patches/drivers/serdev/0003-serdev-add-of_-helper-to-get-serdev-controller.patch @@ -0,0 +1,70 @@ +From 5a117e6146ac68b67a563a931c11664b52b0a158 Mon Sep 17 00:00:00 2001 +From: Vaishnav M A +Date: Sun, 18 Oct 2020 06:28:30 +0530 +Subject: [RFC PATCH 3/5] serdev: add of_ helper to get serdev controller + +add of_find_serdev_controller_by_node to obtain a +serdev_controller from the device_node, which +can help if the serdev_device is not described +over device tree and instantiation of the device +happens from a different driver, for the same purpose +an option to not delete an empty serdev controller +is added. + +Signed-off-by: Vaishnav M A +--- + drivers/tty/serdev/core.c | 17 +++++++++++++++++ + include/linux/serdev.h | 2 ++ + 2 files changed, 19 insertions(+) + +diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c +index 01b248fdc264..85977b36ed7f 100644 +--- a/drivers/tty/serdev/core.c ++++ b/drivers/tty/serdev/core.c +@@ -582,6 +582,17 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl) + return 0; + } + ++struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node) ++{ ++ struct device *dev = bus_find_device_by_of_node(&serdev_bus_type, node); ++ ++ if (!dev) ++ return NULL; ++ ++ return (dev->type == &serdev_ctrl_type) ? to_serdev_controller(dev) : NULL; ++} ++EXPORT_SYMBOL_GPL(of_find_serdev_controller_by_node); ++ + #ifdef CONFIG_ACPI + + #define SERDEV_ACPI_MAX_SCAN_DEPTH 32 +@@ -779,6 +790,12 @@ int serdev_controller_add(struct serdev_controller *ctrl) + + pm_runtime_enable(&ctrl->dev); + ++ /* provide option to not delete a serdev controller without devices ++ * if property is present ++ */ ++ if (device_property_present(&ctrl->dev, "force-empty-serdev-controller")) ++ return 0; ++ + ret_of = of_serdev_register_devices(ctrl); + ret_acpi = acpi_serdev_register_devices(ctrl); + if (ret_of && ret_acpi) { +diff --git a/include/linux/serdev.h b/include/linux/serdev.h +index 0d9c90a250b0..2e1eb4d17e1b 100644 +--- a/include/linux/serdev.h ++++ b/include/linux/serdev.h +@@ -115,6 +115,8 @@ static inline struct serdev_controller *to_serdev_controller(struct device *d) + return container_of(d, struct serdev_controller, dev); + } + ++struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node); ++ + static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev) + { + return dev_get_drvdata(&serdev->dev); +-- +2.25.1 + diff --git a/patches/drivers/serdev/0004-gnss-ubx-add-MODULE_DEVICE_TABLE-serdev.patch b/patches/drivers/serdev/0004-gnss-ubx-add-MODULE_DEVICE_TABLE-serdev.patch new file mode 100644 index 0000000000..5a0badb4f5 --- /dev/null +++ b/patches/drivers/serdev/0004-gnss-ubx-add-MODULE_DEVICE_TABLE-serdev.patch @@ -0,0 +1,42 @@ +From 625e5885def0997235d3153b60adb2e9044fc5c6 Mon Sep 17 00:00:00 2001 +From: Vaishnav M A +Date: Sun, 18 Oct 2020 06:58:01 +0530 +Subject: [RFC PATCH 4/5] gnss: ubx add MODULE_DEVICE_TABLE(serdev) + +export serdev id table to the module header. + +Signed-off-by: Vaishnav M A +--- + drivers/gnss/ubx.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/gnss/ubx.c b/drivers/gnss/ubx.c +index 7b05bc40532e..e50056cc4223 100644 +--- a/drivers/gnss/ubx.c ++++ b/drivers/gnss/ubx.c +@@ -138,6 +138,14 @@ static const struct of_device_id ubx_of_match[] = { + MODULE_DEVICE_TABLE(of, ubx_of_match); + #endif + ++static const struct serdev_device_id ubx_serdev_id[] = { ++ { "neo-6m", }, ++ { "neo-8", }, ++ { "neo-m8", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(serdev, ubx_serdev_id); ++ + static struct serdev_device_driver ubx_driver = { + .driver = { + .name = "gnss-ubx", +@@ -146,6 +154,7 @@ static struct serdev_device_driver ubx_driver = { + }, + .probe = ubx_probe, + .remove = ubx_remove, ++ .id_table = ubx_serdev_id, + }; + module_serdev_device_driver(ubx_driver); + +-- +2.25.1 + diff --git a/patches/drivers/serdev/0005-gnss-change-of_property_read-to-device_property_read.patch b/patches/drivers/serdev/0005-gnss-change-of_property_read-to-device_property_read.patch new file mode 100644 index 0000000000..385e764736 --- /dev/null +++ b/patches/drivers/serdev/0005-gnss-change-of_property_read-to-device_property_read.patch @@ -0,0 +1,35 @@ +From 960e964ca8b6bc8fa60fd9c6a6fd0163e82dad40 Mon Sep 17 00:00:00 2001 +From: Vaishnav M A +Date: Sun, 18 Oct 2020 07:03:27 +0530 +Subject: [RFC PATCH 5/5] gnss: change of_property_read to device_property_read + +change of_property_read_u32 for the current-speed property +to use the device_property_read_u32 offered by the +Unified Device Properties Interface, this helps +passing the properties over a suitably populated struct +property_entry. + +Signed-off-by: Vaishnav M A +--- + drivers/gnss/serial.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gnss/serial.c b/drivers/gnss/serial.c +index def64b36d994..473faeea6aae 100644 +--- a/drivers/gnss/serial.c ++++ b/drivers/gnss/serial.c +@@ -110,10 +110,9 @@ static int gnss_serial_set_power(struct gnss_serial *gserial, + static int gnss_serial_parse_dt(struct serdev_device *serdev) + { + struct gnss_serial *gserial = serdev_device_get_drvdata(serdev); +- struct device_node *node = serdev->dev.of_node; + u32 speed = 4800; + +- of_property_read_u32(node, "current-speed", &speed); ++ device_property_read_u32(&serdev->dev, "current-speed", &speed); + + gserial->speed = speed; + +-- +2.25.1 +