From bf34d5b36031aa6a8f1720205ff3a4de6b5865a5 Mon Sep 17 00:00:00 2001 From: sharma-mts <86847754+sharma-mts@users.noreply.github.com> Date: Fri, 4 Feb 2022 19:41:20 -0600 Subject: Convert mtac driver to use gpio descriptors --- mtac.c | 467 ++++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 247 insertions(+), 220 deletions(-) diff --git a/mtac.c b/mtac.c index 22af08f..749868e 100644 --- a/mtac.c +++ b/mtac.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -19,8 +20,8 @@ /* accessory card EEPROMs, read outside of driver */ uint8_t mts_ap_eeprom[NUM_AP][MTS_AP_EEPROM_SIZE]; EXPORT_SYMBOL(mts_ap_eeprom); - -static const char* eeprom_file_name[NUM_AP] = { + +static const char* eeprom_file_name[NUM_AP] = { #if NUM_AP > 0 #ifdef mtcdt "1-0050/eeprom", "1-0052/eeprom" @@ -45,19 +46,23 @@ void mtac_clear_port_pins(int port_index) char buf[32]; struct gpio_pin *pin; struct gpio_pin *pins; - + snprintf(buf,sizeof buf,"AP%d_",port_index+1); - + /* Find all the GPIO pins for this port and * free them all. */ log_debug("mtac_clear_port_pins: State of mtac mutex is %s", - mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); + mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); mutex_lock(&mtac_mutex); pins = mtac_port_info[port_index]->gpio_pins; for (pin = pins; *pin->name; pin++) { if (!memcmp(pin->name,buf,strlen(buf))) { - gpio_free(pin->pin.gpio); + if (pin->do_gpio_desc) { + gpiod_put(pin->desc); + } else { + gpio_free(pin->pin.gpio); + } } } mtac_port_info[port_index]->gpio_pins = NULL; @@ -76,48 +81,48 @@ void mtac_set_port_pins(int port_index, struct gpio_pin *pins, struct kobject *s EXPORT_SYMBOL(mtac_set_port_pins); struct kobj_attribute* mtac_create_attribute(const char* _name, umode_t _mode) { - char* attr_name; - struct kobj_attribute* _attr; - - _attr = kzalloc(sizeof(struct kobj_attribute), GFP_KERNEL); - if (! _attr) { - log_error("kzalloc of attribute [%s] failed", _name); - return NULL; - } - sysfs_attr_init(_attr); - attr_name = kstrdup(_name, GFP_KERNEL); - if (! attr_name) { - log_error("GFP_KERNEL dup failed for attribute [%s]", _name); - return NULL; - } - _attr->attr.name = attr_name; - _attr->attr.mode = _mode; - - return _attr; + char* attr_name; + struct kobj_attribute* _attr; + + _attr = kzalloc(sizeof(struct kobj_attribute), GFP_KERNEL); + if (! _attr) { + log_error("kzalloc of attribute [%s] failed", _name); + return NULL; + } + sysfs_attr_init(_attr); + attr_name = kstrdup(_name, GFP_KERNEL); + if (! attr_name) { + log_error("GFP_KERNEL dup failed for attribute [%s]", _name); + return NULL; + } + _attr->attr.name = attr_name; + _attr->attr.mode = _mode; + + return _attr; } EXPORT_SYMBOL(mtac_create_attribute); int mtac_port_from_kobject(struct kobject *kobj) { - int port; - const char *name; - - name = kobj->name; - if (! name) { - log_error("kobject->name is NULL"); - return -1; - } - - if (sscanf(name, "ap%d", &port) < 1) { - log_error("failed to scan port from kobject->name [%s]", name); - return -1; - } - - if (port < 1 || port > NUM_AP) { - log_error("port number %d is invalid", port); - return -1; - } - - return port; + int port; + const char *name; + + name = kobj->name; + if (! name) { + log_error("kobject->name is NULL"); + return -1; + } + + if (sscanf(name, "ap%d", &port) < 1) { + log_error("failed to scan port from kobject->name [%s]", name); + return -1; + } + + if (port < 1 || port > NUM_AP) { + log_error("port number %d is invalid", port); + return -1; + } + + return port; } EXPORT_SYMBOL(mtac_port_from_kobject); @@ -126,76 +131,76 @@ EXPORT_SYMBOL(mtac_port_from_kobject); * This function is not normally used directly by mtac modules. */ ssize_t mtac_show_product_info(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - ssize_t value; - int port; - int port_index; - struct mts_ap_eeprom_layout *app; - - port = mtac_port_from_kobject(kobj); - if (port < 1) { - log_error("mtac_port_from_kobject returned %d", port); - return -1; - } - port_index = port - 1; - - app = (struct mts_ap_eeprom_layout *)mts_ap_eeprom[port_index]; - if (! strcmp(attr->attr.name, "vendor-id")) { - value = snprintf(buf, 32, "%s\n", app->vendor_id); - } else if (! strcmp(attr->attr.name, "product-id")) { - value = snprintf(buf, 32, "%s\n", app->product_id); - } else if (! strcmp(attr->attr.name, "device-id")) { - value = snprintf(buf, 32, "%s\n", app->device_id); - } else if (! strcmp(attr->attr.name, "hw-version")) { - value = snprintf(buf, 32, "%s\n", app->hw_version); - } else { - log_error("attribute [%s] not found", attr->attr.name); - value = -1; - } - return value; + ssize_t value; + int port; + int port_index; + struct mts_ap_eeprom_layout *app; + + port = mtac_port_from_kobject(kobj); + if (port < 1) { + log_error("mtac_port_from_kobject returned %d", port); + return -1; + } + port_index = port - 1; + + app = (struct mts_ap_eeprom_layout *)mts_ap_eeprom[port_index]; + if (! strcmp(attr->attr.name, "vendor-id")) { + value = snprintf(buf, 32, "%s\n", app->vendor_id); + } else if (! strcmp(attr->attr.name, "product-id")) { + value = snprintf(buf, 32, "%s\n", app->product_id); + } else if (! strcmp(attr->attr.name, "device-id")) { + value = snprintf(buf, 32, "%s\n", app->device_id); + } else if (! strcmp(attr->attr.name, "hw-version")) { + value = snprintf(buf, 32, "%s\n", app->hw_version); + } else { + log_error("attribute [%s] not found", attr->attr.name); + value = -1; + } + return value; } EXPORT_SYMBOL(mtac_show_product_info); bool mtac_add_product_info_attributes(int port, struct attribute** attrs, int* index) { - char buf[32]; - struct kobj_attribute* kobj_attr; - - sprintf(buf, "vendor-id"); - kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO); - if (! kobj_attr) { - log_error("failed to create attribute [%s] in port %d", buf, port); - return false; - } - kobj_attr->show = mtac_show_product_info; - attrs[(*index)++] = &kobj_attr->attr; - - sprintf(buf, "product-id"); - kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO); - if (! kobj_attr) { - log_error("failed to create attribute [%s] in port %d", buf, port); - return false; - } - kobj_attr->show = mtac_show_product_info; - attrs[(*index)++] = &kobj_attr->attr; - - sprintf(buf, "device-id"); - kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO); - if (! kobj_attr) { - log_error("failed to create attribute [%s] in port %d", buf, port); - return false; - } - kobj_attr->show = mtac_show_product_info; - attrs[(*index)++] = &kobj_attr->attr; - - sprintf(buf, "hw-version"); - kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO); - if (! kobj_attr) { - log_error("failed to create attribute [%s] in port %d", buf, port); - return false; - } - kobj_attr->show = mtac_show_product_info; - attrs[(*index)++] = &kobj_attr->attr; - - return true; + char buf[32]; + struct kobj_attribute* kobj_attr; + + sprintf(buf, "vendor-id"); + kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO); + if (! kobj_attr) { + log_error("failed to create attribute [%s] in port %d", buf, port); + return false; + } + kobj_attr->show = mtac_show_product_info; + attrs[(*index)++] = &kobj_attr->attr; + + sprintf(buf, "product-id"); + kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO); + if (! kobj_attr) { + log_error("failed to create attribute [%s] in port %d", buf, port); + return false; + } + kobj_attr->show = mtac_show_product_info; + attrs[(*index)++] = &kobj_attr->attr; + + sprintf(buf, "device-id"); + kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO); + if (! kobj_attr) { + log_error("failed to create attribute [%s] in port %d", buf, port); + return false; + } + kobj_attr->show = mtac_show_product_info; + attrs[(*index)++] = &kobj_attr->attr; + + sprintf(buf, "hw-version"); + kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO); + if (! kobj_attr) { + log_error("failed to create attribute [%s] in port %d", buf, port); + return false; + } + kobj_attr->show = mtac_show_product_info; + attrs[(*index)++] = &kobj_attr->attr; + + return true; } EXPORT_SYMBOL(mtac_add_product_info_attributes); @@ -204,27 +209,27 @@ EXPORT_SYMBOL(mtac_add_product_info_attributes); * This function is not normally used directly by mtac modules. */ struct gpio_pin *mtac_gpio_pin_by_attr_name(const char *name, int port) { - struct gpio_pin *pin; - char *pin_attr_name; - int port_index = port - 1; - struct gpio_pin *port_gpio_pins; - - log_debug("mtac_gpio_pin_by_attr_name: State of mtac mutex is %s", - mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); - mutex_lock(&mtac_mutex); - pin_attr_name = mtac_port_info[port_index]->gpio_pin_name_by_attr_name(name, port); - port_gpio_pins = mtac_port_info[port_index]->gpio_pins; - - for (pin = port_gpio_pins; *pin->name; pin++) { - if (!strcmp(pin->pin.label, pin_attr_name)) { - mutex_unlock(&mtac_mutex); - return pin; - } - } - mutex_unlock(&mtac_mutex); - - log_error("pin with attr name [%s] not found", name); - return NULL; + struct gpio_pin *pin; + char *pin_attr_name; + int port_index = port - 1; + struct gpio_pin *port_gpio_pins; + + log_debug("mtac_gpio_pin_by_attr_name: State of mtac mutex is %s", + mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); + mutex_lock(&mtac_mutex); + pin_attr_name = mtac_port_info[port_index]->gpio_pin_name_by_attr_name(name, port); + port_gpio_pins = mtac_port_info[port_index]->gpio_pins; + + for (pin = port_gpio_pins; *pin->name; pin++) { + if (!strcmp(pin->pin.label, pin_attr_name)) { + mutex_unlock(&mtac_mutex); + return pin; + } + } + mutex_unlock(&mtac_mutex); + + log_error("pin with attr name [%s] not found", name); + return NULL; } EXPORT_SYMBOL(mtac_gpio_pin_by_attr_name); @@ -235,32 +240,36 @@ ssize_t mtac_attr_show_ap_gpio_pin(struct kobject *kobj, int value; int port; struct gpio_pin *pin; - + port = mtac_port_from_kobject(kobj); if (port < 1) { - log_error("mtac_port_from_kobject returned %d", port); - return -EINVAL; + log_error("mtac_port_from_kobject returned %d", port); + return -EINVAL; } pin = mtac_gpio_pin_by_attr_name(attr->attr.name, port); if (!pin) { - return -ENODEV; + return -ENODEV; } log_debug("mtac_attr_show_ap_gpio_pin: State of mtac mutex is %s", - mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); + mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); mutex_lock(&mtac_mutex); - value = gpio_get_value(pin->pin.gpio); + if (pin->do_gpio_desc) { + value = gpiod_get_value(pin->desc); + } else { + value = gpio_get_value(pin->pin.gpio); + } mutex_unlock(&mtac_mutex); if (value < 0) { - return value; + return value; } if (pin->active_low) { - value = !value; + value = !value; } return sprintf(buf, "%d\n", value); @@ -271,45 +280,48 @@ EXPORT_SYMBOL(mtac_attr_show_ap_gpio_pin); ssize_t mtac_attr_store_ap_gpio_pin(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { - int value; - int port; - struct gpio_pin *pin; - - port = mtac_port_from_kobject(kobj); - if (port < 1) { - log_error("mtac_port_from_kobject returned %d", port); - return -EINVAL; - } - - pin = mtac_gpio_pin_by_attr_name(attr->attr.name, port); - if (!pin) { - return -ENODEV; - } - - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } - - if (pin->active_low) { - value = !value; - } - - log_debug("mtac_attr_store_ap_gpio_pin: State of mtac mutex is %s", - mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); - mutex_lock(&mtac_mutex); - - gpio_set_value(pin->pin.gpio, value); - - mutex_unlock(&mtac_mutex); - - return count; + int value; + int port; + struct gpio_pin *pin; + + port = mtac_port_from_kobject(kobj); + if (port < 1) { + log_error("mtac_port_from_kobject returned %d", port); + return -EINVAL; + } + + pin = mtac_gpio_pin_by_attr_name(attr->attr.name, port); + if (!pin) { + return -ENODEV; + } + + if (sscanf(buf, "%i", &value) != 1) { + return -EINVAL; + } + + if (pin->active_low) { + value = !value; + } + + log_debug("mtac_attr_store_ap_gpio_pin: State of mtac mutex is %s", + mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); + mutex_lock(&mtac_mutex); + + if (pin->do_gpio_desc) { + gpiod_set_value(pin->desc, value); + } else { + gpio_set_value(pin->pin.gpio, value); + } + mutex_unlock(&mtac_mutex); + + return count; } EXPORT_SYMBOL(mtac_attr_store_ap_gpio_pin); static void display_port(int port_index) { int port = port_index + 1; struct mts_ap_eeprom_layout *app; - + /* Our caller has locked the mtac_mutex */ if(!mutex_is_locked(&mtac_mutex)) @@ -325,40 +337,55 @@ static void display_port(int port_index) { static void acquire_gpio(struct gpio_pin *pins, int port_index) { - char buf[32]; - struct gpio_pin *pin; - int ret; - - snprintf(buf,sizeof buf,"AP%d_",port_index+1); - for (pin = pins; *pin->name; pin++) { - if (!memcmp(pin->name,buf,strlen(buf))) { - log_debug("Request name:%s label: %s pin: %d", pin->name, pin->pin.label, pin->pin.gpio); - ret = gpio_request_one(pin->pin.gpio, pin->pin.flags, pin->pin.label); - if (ret) - log_debug("could not request pin %s (%d) but it could have already been requested under a different pin name", pin->name, ret); - } - } + char buf[32]; + struct gpio_pin *pin; + int ret; + + snprintf(buf,sizeof buf,"AP%d_",port_index+1); + for (pin = pins; *pin->name; pin++) { + if (!memcmp(pin->name,buf,strlen(buf))) { + if (pin->do_gpio_desc) { + log_debug("Request name:%s label: %s", pin->name, pin->pin.label); + pin->desc = devm_gpiod_get_optional(&mts_io_platform_device->dev, pin->name, pin->pin.flags); + if (IS_ERR(pin->desc)) { + dev_dbg(&mts_io_platform_device->dev, + "%s: Could not get gpio %s: Error: %ld\n", __func__, pin->name, PTR_ERR(pin->desc)); + } else { + if (pin->desc == NULL) + dev_dbg(&mts_io_platform_device->dev,"gpio_desc is null for name: %s, label: %s\n", + pin->name, pin->pin.label); + else + dev_dbg(&mts_io_platform_device->dev,"Found gpio %s\n", pin->name); + } + } else { + log_debug("Request name:%s label: %s pin: %d", pin->name, pin->pin.label, pin->pin.gpio); + ret = gpio_request_one(pin->pin.gpio, pin->pin.flags, pin->pin.label); + if (ret) + log_debug("could not request pin %s (%d) but it could have already been requested under a different pin name", pin->name, ret); + } + } + } } #include struct gpio_pin *mtac_gpio_pin_by_name(const char *name, int port_index) { - struct gpio_pin *pin; - - log_debug("mtac_gpio_pin_by_name: State of mtac mutex is %s", - mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); - mutex_lock(&mtac_mutex); - for (pin = mtac_port_info[port_index]->gpio_pins; *pin->name; pin++) { - if (!strcmp(pin->name, name)) { - mutex_unlock(&mtac_mutex); - return pin; - } - } - mutex_unlock(&mtac_mutex); - - log_error("pin named %s not found", name); - - return NULL; + struct gpio_pin *pin; + + log_debug("mtac_gpio_pin_by_name: State of mtac mutex is %s", + mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); + mutex_lock(&mtac_mutex); + for (pin = mtac_port_info[port_index]->gpio_pins; *pin->name; pin++) { + if (!strcmp(pin->name, name)) { + mutex_unlock(&mtac_mutex); + return pin; + } + } + mutex_unlock(&mtac_mutex); + + log_error("pin named %s not found", name); + + return NULL; } EXPORT_SYMBOL(mtac_gpio_pin_by_name); @@ -366,24 +393,24 @@ EXPORT_SYMBOL(mtac_gpio_pin_by_name); /* static gpio_pins */ // A GPIO pin number must only occur once. struct gpio_pin *mtac_gpio_pin_by_num(unsigned num, int port_index) { - int ipin = 0; - struct gpio_pin *port_gpio_pins; - - log_debug("mtac_gpio_pin_by_num: State of mtac mutex is %s", - mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); - mutex_lock(&mtac_mutex); - port_gpio_pins = mtac_port_info[port_index]->gpio_pins; - while(*(port_gpio_pins[ipin].name)) { - if (port_gpio_pins[ipin].pin.gpio == num) { - mutex_unlock(&mtac_mutex); - return &(port_gpio_pins[ipin]); - } - ipin++; - } - mutex_unlock(&mtac_mutex); - log_error("pin numbered %u not found", num); - - return NULL; + int ipin = 0; + struct gpio_pin *port_gpio_pins; + + log_debug("mtac_gpio_pin_by_num: State of mtac mutex is %s", + mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked"); + mutex_lock(&mtac_mutex); + port_gpio_pins = mtac_port_info[port_index]->gpio_pins; + while(*(port_gpio_pins[ipin].name)) { + if (port_gpio_pins[ipin].pin.gpio == num) { + mutex_unlock(&mtac_mutex); + return &(port_gpio_pins[ipin]); + } + ipin++; + } + mutex_unlock(&mtac_mutex); + log_error("pin numbered %u not found", num); + + return NULL; } EXPORT_SYMBOL(mtac_gpio_pin_by_num); @@ -464,7 +491,7 @@ void mtac_free(const char *product_id, bool(* setup)(enum ap port), const char * log_debug("setup: %p setup ptr: %p",mtac_port_info[port_index]->setup,setup); if (mtac_port_info[port_index] && (mtac_port_info[port_index]->setup == setup)) { log_debug("port_index %d is occupied by us, teardown next",port_index); - + if (count > 1) { sprintf(buf, "%s-%d",link,port); } else { -- cgit v1.2.3