core: don't duplicate chip-related data structures
authorBartosz Golaszewski <bartekgola@gmail.com>
Sat, 1 Jul 2017 11:54:33 +0000 (13:54 +0200)
committerBartosz Golaszewski <bartekgola@gmail.com>
Thu, 6 Jul 2017 09:11:36 +0000 (11:11 +0200)
Introduce an internal structure - line_chip_ctx - used to store the
chip-related information. This structure is shared among all line
objects exposed by a single chip.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
src/lib/chip.c
src/lib/line.c
src/lib/line.h

index fa82784c1c298d928d53feb45db9f3458474a2ae..093fe90dcf421fa74242c1af359035bc04b36a70 100644 (file)
@@ -23,6 +23,7 @@ struct gpiod_chip {
        int fd;
        struct gpiochip_info cinfo;
        struct gpiod_line **lines;
+       struct line_chip_ctx *chip_ctx;
 };
 
 static bool isuint(const char *str)
@@ -156,6 +157,9 @@ void gpiod_chip_close(struct gpiod_chip *chip)
                }
        }
 
+       if (chip->chip_ctx)
+               line_chip_ctx_free(chip->chip_ctx);
+
        close(chip->fd);
        free(chip->lines);
        free(chip);
@@ -187,8 +191,14 @@ gpiod_chip_get_line(struct gpiod_chip *chip, unsigned int offset)
                return NULL;
        }
 
+       if (!chip->chip_ctx) {
+               chip->chip_ctx = line_chip_ctx_new(chip, chip->fd);
+               if (!chip->chip_ctx)
+                       return NULL;
+       }
+
        if (!chip->lines[offset]) {
-               line = line_new(offset, chip, chip->fd);
+               line = line_new(offset, chip->chip_ctx);
                if (!line)
                        return NULL;
 
index 0f60ccad90336c12f304acd192b5e352bc7c801c..02a9469321f540d35f157c269f6915e31f135957 100644 (file)
@@ -29,11 +29,15 @@ struct handle_data {
        int refcount;
 };
 
+struct line_chip_ctx {
+       int fd;
+       struct gpiod_chip *chip;
+};
+
 struct gpiod_line {
        int state;
        bool up_to_date;
-       struct gpiod_chip *chip;
-       int fd;
+       struct line_chip_ctx *chip_ctx;
        struct gpioline_info info;
        union {
                struct handle_data *handle;
@@ -86,8 +90,27 @@ static void line_remove_handle(struct gpiod_line *line)
        }
 }
 
-struct gpiod_line *
-line_new(unsigned int offset, struct gpiod_chip *chip, int info_fd)
+struct line_chip_ctx * line_chip_ctx_new(struct gpiod_chip *chip, int fd)
+{
+       struct line_chip_ctx *chip_ctx;
+
+       chip_ctx = malloc(sizeof(*chip_ctx));
+       if (!chip_ctx)
+               return NULL;
+
+       chip_ctx->chip = chip;
+       chip_ctx->fd = fd;
+
+       return chip_ctx;
+}
+
+void line_chip_ctx_free(struct line_chip_ctx *chip_ctx)
+{
+       free(chip_ctx);
+}
+
+struct gpiod_line * line_new(unsigned int offset,
+                            struct line_chip_ctx *chip_ctx)
 {
        struct gpiod_line *line;
 
@@ -98,8 +121,7 @@ line_new(unsigned int offset, struct gpiod_chip *chip, int info_fd)
        memset(line, 0, sizeof(*line));
 
        line->info.line_offset = offset;
-       line->chip = chip;
-       line->fd = info_fd;
+       line->chip_ctx = chip_ctx;
 
        return line;
 }
@@ -116,12 +138,7 @@ void line_set_offset(struct gpiod_line *line, unsigned int offset)
 
 struct gpiod_chip * gpiod_line_get_chip(struct gpiod_line *line)
 {
-       return line->chip;
-}
-
-void line_set_chip(struct gpiod_line *line, struct gpiod_chip *chip)
-{
-       line->chip = chip;
+       return line->chip_ctx->chip;
 }
 
 unsigned int gpiod_line_offset(struct gpiod_line *line)
@@ -217,14 +234,14 @@ bool gpiod_line_needs_update(struct gpiod_line *line)
 
 int gpiod_line_update(struct gpiod_line *line)
 {
-       int status;
+       int rv;
 
        memset(line->info.name, 0, sizeof(line->info.name));
        memset(line->info.consumer, 0, sizeof(line->info.consumer));
        line->info.flags = 0;
 
-       status = ioctl(line->fd, GPIO_GET_LINEINFO_IOCTL, &line->info);
-       if (status < 0)
+       rv = ioctl(line->chip_ctx->fd, GPIO_GET_LINEINFO_IOCTL, &line->info);
+       if (rv < 0)
                return -1;
 
        line_set_updated(line);
@@ -340,7 +357,7 @@ int gpiod_line_request_bulk(struct gpiod_line_bulk *bulk,
        strncpy(req->consumer_label, config->consumer,
                sizeof(req->consumer_label) - 1);
 
-       fd = bulk->lines[0]->fd;
+       fd = bulk->lines[0]->chip_ctx->fd;
 
        status = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, req);
        if (status < 0)
@@ -543,7 +560,7 @@ int gpiod_line_event_request(struct gpiod_line *line,
                             struct gpiod_line_evreq_config *config)
 {
        struct gpioevent_request *req;
-       int status;
+       int rv;
 
        if (!gpiod_line_is_free(line)) {
                errno = EBUSY;
@@ -573,8 +590,8 @@ int gpiod_line_event_request(struct gpiod_line *line,
        else if (config->event_type == GPIOD_EVENT_BOTH_EDGES)
                req->eventflags |= GPIOEVENT_REQUEST_BOTH_EDGES;
 
-       status = ioctl(line->fd, GPIO_GET_LINEEVENT_IOCTL, req);
-       if (status < 0)
+       rv = ioctl(line->chip_ctx->fd, GPIO_GET_LINEEVENT_IOCTL, req);
+       if (rv < 0)
                return -1;
 
        line_set_state(line, LINE_EVENT);
index 3ffb0882d9b761cf65c2176224a7f012b43eaee1..84e2967885ea28c9caa5f75d51c6f0ab969786d4 100644 (file)
 
 #include <gpiod.h>
 
-struct gpiod_line *
-line_new(unsigned int offset, struct gpiod_chip *chip, int info_fd);
+struct line_chip_ctx;
+
+struct line_chip_ctx * line_chip_ctx_new(struct gpiod_chip *chip, int fd);
+void line_chip_ctx_free(struct line_chip_ctx *chip_ctx);
+
+struct gpiod_line * line_new(unsigned int offset,
+                            struct line_chip_ctx *chip_ctx);
 void line_free(struct gpiod_line *line);
 
 #endif /* __GPIOD_INTERNAL_LINE_H__ */