Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Rework Apple SMC attachment goo and split into multiple ...



details:   https://anonhg.NetBSD.org/src/rev/29f99a556ebe
branches:  trunk
changeset: 328371:29f99a556ebe
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Tue Apr 01 17:48:39 2014 +0000

description:
Rework Apple SMC attachment goo and split into multiple modules.

The four modules are apple_smc for the core functions, apple_smc_acpi
for attachment at acpi, and apple_smc_fan & apple_smc_temp for stuff
on the SMC.

Seems like there's a lot more bookkeeping necessary to maintain
children of an applesmc device implemented by loadable modules.
Maybe there's a better way I just haven't figured out yet.

diffstat:

 sys/conf/files                                   |    7 +-
 sys/dev/acpi/apple_smc_acpi.c                    |   72 ++++-
 sys/dev/ic/apple_smc.c                           |  330 +++++++++++++++++++---
 sys/dev/ic/apple_smc.h                           |    8 +-
 sys/dev/ic/apple_smc_fan.c                       |   53 +++-
 sys/dev/ic/apple_smc_temp.c                      |   53 +++-
 sys/dev/ic/apple_smcvar.h                        |   19 +-
 sys/modules/apple_smc/Makefile                   |    6 +-
 sys/modules/apple_smc_acpi/Makefile              |   15 +
 sys/modules/apple_smc_acpi/apple_smc_acpi.ioconf |   10 +
 sys/modules/apple_smc_fan/Makefile               |   15 +
 sys/modules/apple_smc_fan/apple_smc_fan.ioconf   |    9 +
 sys/modules/apple_smc_temp/Makefile              |   15 +
 sys/modules/apple_smc_temp/apple_smc_temp.ioconf |    9 +
 14 files changed, 545 insertions(+), 76 deletions(-)

diffs (truncated from 902 to 300 lines):

diff -r 0f0153865661 -r 29f99a556ebe sys/conf/files
--- a/sys/conf/files    Tue Apr 01 17:47:36 2014 +0000
+++ b/sys/conf/files    Tue Apr 01 17:48:39 2014 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files,v 1.1088 2014/04/01 17:47:36 riastradh Exp $
+#      $NetBSD: files,v 1.1089 2014/04/01 17:48:39 riastradh Exp $
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
 
 version        20100430
@@ -1097,7 +1097,8 @@
 
 # Apple System Management Controller
 #
-device applesmc {}
+define applesmcbus     { }
+device applesmc        { }: applesmcbus
 file   dev/ic/apple_smc.c              applesmc
 
 # Apple SMC fan sensors and control
@@ -1110,7 +1111,7 @@
 attach applesmctemp at applesmc with apple_smc_temp
 file   dev/ic/apple_smc_temp.c         applesmctemp
 
-# Apple SMC accelerometer
+# Apple SMC accelerometer (not yet implemented!)
 #device        applesmcaccel: applesmc, sysmon_envsys
 #attach        applesmcaccel at applesmc with apple_smc_accel
 #file  dev/ic/apple_smc_accel.c        applesmcaccel
diff -r 0f0153865661 -r 29f99a556ebe sys/dev/acpi/apple_smc_acpi.c
--- a/sys/dev/acpi/apple_smc_acpi.c     Tue Apr 01 17:47:36 2014 +0000
+++ b/sys/dev/acpi/apple_smc_acpi.c     Tue Apr 01 17:48:39 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: apple_smc_acpi.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $     */
+/*     $NetBSD: apple_smc_acpi.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $     */
 
 /*
  * Apple System Management Controller: ACPI Attachment
@@ -31,10 +31,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apple_smc_acpi.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apple_smc_acpi.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/module.h>
 
 #include <dev/acpi/acpireg.h>
 #include <dev/acpi/acpivar.h>
@@ -52,9 +54,16 @@
 static int     apple_smc_acpi_match(device_t, cfdata_t, void *);
 static void    apple_smc_acpi_attach(device_t, device_t, void *);
 static int     apple_smc_acpi_detach(device_t, int);
-
-CFATTACH_DECL_NEW(apple_smc_acpi, sizeof(struct apple_smc_acpi_softc),
-    apple_smc_acpi_match, apple_smc_acpi_attach, apple_smc_acpi_detach, NULL);
+static int     apple_smc_acpi_rescan(device_t, const char *, const int *);
+static void    apple_smc_acpi_child_detached(device_t, device_t);
+
+CFATTACH_DECL2_NEW(apple_smc_acpi, sizeof(struct apple_smc_acpi_softc),
+    apple_smc_acpi_match,
+    apple_smc_acpi_attach,
+    apple_smc_acpi_detach,
+    NULL /* activate */,
+    apple_smc_acpi_rescan,
+    apple_smc_acpi_child_detached);
 
 static const char *const apple_smc_ids[] = {
        "APP0001",
@@ -143,3 +152,56 @@
 
        return 0;
 }
+
+static int
+apple_smc_acpi_rescan(device_t self, const char *ifattr, const int *locs)
+{
+       struct apple_smc_acpi_softc *const sc = device_private(self);
+
+       return apple_smc_rescan(&sc->sc_smc, ifattr, locs);
+}
+
+static void
+apple_smc_acpi_child_detached(device_t self, device_t child)
+{
+       struct apple_smc_acpi_softc *const sc = device_private(self);
+
+       apple_smc_child_detached(&sc->sc_smc, child);
+}
+
+MODULE(MODULE_CLASS_DRIVER, apple_smc_acpi, "apple_smc");
+
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+
+static int
+apple_smc_acpi_modcmd(modcmd_t cmd, void *arg __unused)
+{
+       int error;
+
+       switch (cmd) {
+       case MODULE_CMD_INIT:
+#ifdef _MODULE
+               error = config_init_component(cfdriver_ioconf_apple_smc_acpi,
+                   cfattach_ioconf_apple_smc_acpi,
+                   cfdata_ioconf_apple_smc_acpi);
+               if (error)
+                       return error;
+#endif
+               return 0;
+
+       case MODULE_CMD_FINI:
+#ifdef _MODULE
+               error = config_fini_component(cfdriver_ioconf_apple_smc_acpi,
+                   cfattach_ioconf_apple_smc_acpi,
+                   cfdata_ioconf_apple_smc_acpi);
+               if (error)
+                       return error;
+#endif
+               return 0;
+
+       default:
+               return ENOTTY;
+       }
+}
diff -r 0f0153865661 -r 29f99a556ebe sys/dev/ic/apple_smc.c
--- a/sys/dev/ic/apple_smc.c    Tue Apr 01 17:47:36 2014 +0000
+++ b/sys/dev/ic/apple_smc.c    Tue Apr 01 17:48:39 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: apple_smc.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $  */
+/*     $NetBSD: apple_smc.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $  */
 
 /*
  * Apple System Management Controller
@@ -34,14 +34,17 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apple_smc.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apple_smc.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/device.h>
 #include <sys/errno.h>
 #include <sys/kmem.h>
+#include <sys/module.h>
 #include <sys/mutex.h>
+#include <sys/rbtree.h>
+#include <sys/rwlock.h>
 #if 0                           /* XXX sysctl */
 #include <sys/sysctl.h>
 #endif
@@ -51,9 +54,13 @@
 #include <dev/ic/apple_smcreg.h>
 #include <dev/ic/apple_smcvar.h>
 
-static void    apple_smc_rescan1(struct apple_smc_tag *,
-                   struct apple_smc_attach_args *,
-                   const char *, const char *, device_t *);
+#define        APPLE_SMC_BUS   "applesmcbus"
+
+static int     apple_smc_dev_compare_nodes(void *, const void *,
+                   const void *);
+static int     apple_smc_dev_compare_key(void *, const void *, const void *);
+static int     apple_smc_init(void);
+static int     apple_smc_fini(void);
 static uint8_t apple_smc_bus_read_1(struct apple_smc_tag *, bus_size_t);
 static void    apple_smc_bus_write_1(struct apple_smc_tag *, bus_size_t,
                    uint8_t);
@@ -67,12 +74,151 @@
                    const char *, void *, uint8_t);
 static int     apple_smc_output(struct apple_smc_tag *, uint8_t,
                    const char *, const void *, uint8_t);
+
+struct apple_smc_dev {
+       char            asd_name[APPLE_SMC_DEVICE_NAME_SIZE];
+       rb_node_t       asd_node;
+       device_t        asd_dev[];
+};
 
+static int
+apple_smc_dev_compare_nodes(void *context __unused, const void *va,
+    const void *vb)
+{
+       const struct apple_smc_dev *const a = va;
+       const struct apple_smc_dev *const b = vb;
+
+       return strncmp(a->asd_name, b->asd_name, APPLE_SMC_DEVICE_NAME_SIZE);
+}
+
+static int
+apple_smc_dev_compare_key(void *context __unused, const void *vn,
+    const void *vk)
+{
+       const struct apple_smc_dev *const dev = vn;
+       const char *const key = vk;
+
+       return strncmp(dev->asd_name, key, APPLE_SMC_DEVICE_NAME_SIZE);
+}
+
+static krwlock_t apple_smc_registered_devices_lock;
+static rb_tree_t apple_smc_registered_devices;
+static unsigned int apple_smc_n_registered_devices;
+
+static const rb_tree_ops_t apple_smc_dev_tree_ops = {
+       .rbto_compare_nodes     = &apple_smc_dev_compare_nodes,
+       .rbto_compare_key       = &apple_smc_dev_compare_key,
+       .rbto_node_offset       = offsetof(struct apple_smc_dev, asd_node),
+};
+
+static int
+apple_smc_init(void)
+{
+
+       rw_init(&apple_smc_registered_devices_lock);
+       rb_tree_init(&apple_smc_registered_devices, &apple_smc_dev_tree_ops);
+       apple_smc_n_registered_devices = 0;
+
+       /* Success!  */
+       return 0;
+}
+
+static int
+apple_smc_fini(void)
+{
+
+       /* Refuse to unload if there remain any registered devices.  */
+       if (apple_smc_n_registered_devices)
+               return EBUSY;
+
+       /* The tree should be empty in this case.  */
+       KASSERT(rb_tree_iterate(&apple_smc_registered_devices, NULL,
+               RB_DIR_RIGHT) == NULL);
+
+#if 0                          /* XXX no rb_tree_destroy */
+       rb_tree_destroy(&apple_smc_registered_devices);
+#endif
+       rw_destroy(&apple_smc_registered_devices_lock);
+
+       /* Success!  */
+       return 0;
+}
+
+int
+apple_smc_register_device(const char name[APPLE_SMC_DEVICE_NAME_SIZE])
+{
+       int error;
+
+       /* Paranoia about null termination.  */
+       KASSERT(name[strnlen(name, (sizeof(name) - 1))] == '\0');
+
+       /* Make a new record for the registration.  */
+       struct apple_smc_dev *const dev =
+           kmem_alloc(offsetof(struct apple_smc_dev, asd_dev[0]), KM_SLEEP);
+       (void)strlcpy(dev->asd_name, name, sizeof(dev->asd_name));
+
+       rw_enter(&apple_smc_registered_devices_lock, RW_WRITER);
+
+       /* Fail if there are too many.  We really oughtn't get here.  */
+       if (apple_smc_n_registered_devices == UINT_MAX) {
+               error = ENOMEM;
+               goto out;
+       }
+
+       /* Fail if the name is already registered.  */
+       struct apple_smc_dev *const collision =
+           rb_tree_insert_node(&apple_smc_registered_devices, dev);
+       if (collision != dev) {
+               kmem_free(dev, offsetof(struct apple_smc_dev, asd_dev[0]));
+               error = EEXIST;
+               goto out;
+       }
+
+       /* Success!  */
+       apple_smc_n_registered_devices++;
+       error = 0;
+
+out:
+       rw_exit(&apple_smc_registered_devices_lock);
+       return error;
+}
+
+void
+apple_smc_unregister_device(const char name[APPLE_SMC_DEVICE_NAME_SIZE])
+{
+
+       KASSERT(name[strnlen(name, (sizeof(name) - 1))] == '\0');
+
+       rw_enter(&apple_smc_registered_devices_lock, RW_WRITER);
+
+       /* Find the node.  */
+       struct apple_smc_dev *const dev =
+           rb_tree_find_node(&apple_smc_registered_devices, name);
+       if (dev == NULL) {
+               printf("%s: device was never registered: %s\n", __func__,
+                   name);



Home | Main Index | Thread Index | Old Index