Commit f4277a0e authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/gpio: move on-reset intr disable-and-ack to common code



Re-uses the implementation's accessor functions rather than requiring
and init/fini implementation for each chipset.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 5693c0f2
Loading
Loading
Loading
Loading
+52 −18
Original line number Diff line number Diff line
@@ -134,6 +134,46 @@ nouveau_gpio_intr(struct nouveau_subdev *subdev)
	}
}

int
_nouveau_gpio_fini(struct nouveau_object *object, bool suspend)
{
	const struct nouveau_gpio_impl *impl = (void *)object->oclass;
	struct nouveau_gpio *gpio = nouveau_gpio(object);
	u32 mask = (1 << impl->lines) - 1;

	impl->intr_mask(gpio, NVKM_GPIO_TOGGLED, mask, 0);
	impl->intr_stat(gpio, &mask, &mask);

	return nouveau_subdev_fini(&gpio->base, suspend);
}

static struct dmi_system_id gpio_reset_ids[] = {
	{
		.ident = "Apple Macbook 10,1",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
		}
	},
	{ }
};

int
_nouveau_gpio_init(struct nouveau_object *object)
{
	struct nouveau_gpio *gpio = nouveau_gpio(object);
	int ret;

	ret = nouveau_subdev_init(&gpio->base);
	if (ret)
		return ret;

	if (gpio->reset && dmi_check_system(gpio_reset_ids))
		gpio->reset(gpio, DCB_GPIO_UNUSED);

	return ret;
}

void
_nouveau_gpio_dtor(struct nouveau_object *object)
{
@@ -173,24 +213,18 @@ nouveau_gpio_create_(struct nouveau_object *parent,
	return 0;
}

static struct dmi_system_id gpio_reset_ids[] = {
	{
		.ident = "Apple Macbook 10,1",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
		}
	},
	{ }
};

int
nouveau_gpio_init(struct nouveau_gpio *gpio)
_nouveau_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
		   struct nouveau_oclass *oclass, void *data, u32 size,
		   struct nouveau_object **pobject)
{
	int ret = nouveau_subdev_init(&gpio->base);
	if (ret == 0 && gpio->reset) {
		if (dmi_check_system(gpio_reset_ids))
			gpio->reset(gpio, DCB_GPIO_UNUSED);
	}
	struct nouveau_gpio *gpio;
	int ret;

	ret = nouveau_gpio_create(parent, engine, oclass, &gpio);
	*pobject = nv_object(gpio);
	if (ret)
		return ret;

	return 0;
}
+3 −33
Original line number Diff line number Diff line
@@ -121,44 +121,14 @@ nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
	return 0;
}

static void
nv10_gpio_dtor(struct nouveau_object *object)
{
	struct nv10_gpio_priv *priv = (void *)object;
	nouveau_gpio_destroy(&priv->base);
}

static int
nv10_gpio_init(struct nouveau_object *object)
{
	struct nv10_gpio_priv *priv = (void *)object;
	int ret;

	ret = nouveau_gpio_init(&priv->base);
	if (ret)
		return ret;

	nv_wr32(priv, 0x001144, 0x00000000);
	nv_wr32(priv, 0x001104, 0xffffffff);
	return 0;
}

static int
nv10_gpio_fini(struct nouveau_object *object, bool suspend)
{
	struct nv10_gpio_priv *priv = (void *)object;
	nv_wr32(priv, 0x001144, 0x00000000);
	return nouveau_gpio_fini(&priv->base, suspend);
}

struct nouveau_oclass *
nv10_gpio_oclass = &(struct nouveau_gpio_impl) {
	.base.handle = NV_SUBDEV(GPIO, 0x10),
	.base.ofuncs = &(struct nouveau_ofuncs) {
		.ctor = nv10_gpio_ctor,
		.dtor = nv10_gpio_dtor,
		.init = nv10_gpio_init,
		.fini = nv10_gpio_fini,
		.dtor = _nouveau_gpio_dtor,
		.init = _nouveau_gpio_init,
		.fini = _nouveau_gpio_fini,
	},
	.lines = 16,
	.intr_stat = nv10_gpio_intr_stat,
+3 −41
Original line number Diff line number Diff line
@@ -135,52 +135,14 @@ nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
	return 0;
}

void
nv50_gpio_dtor(struct nouveau_object *object)
{
	struct nv50_gpio_priv *priv = (void *)object;
	nouveau_gpio_destroy(&priv->base);
}

int
nv50_gpio_init(struct nouveau_object *object)
{
	struct nv50_gpio_priv *priv = (void *)object;
	int ret;

	ret = nouveau_gpio_init(&priv->base);
	if (ret)
		return ret;

	/* disable, and ack any pending gpio interrupts */
	nv_wr32(priv, 0xe050, 0x00000000);
	nv_wr32(priv, 0xe054, 0xffffffff);
	if (nv_device(priv)->chipset > 0x92) {
		nv_wr32(priv, 0xe070, 0x00000000);
		nv_wr32(priv, 0xe074, 0xffffffff);
	}

	return 0;
}

int
nv50_gpio_fini(struct nouveau_object *object, bool suspend)
{
	struct nv50_gpio_priv *priv = (void *)object;
	nv_wr32(priv, 0xe050, 0x00000000);
	if (nv_device(priv)->chipset > 0x92)
		nv_wr32(priv, 0xe070, 0x00000000);
	return nouveau_gpio_fini(&priv->base, suspend);
}

struct nouveau_oclass *
nv50_gpio_oclass = &(struct nouveau_gpio_impl) {
	.base.handle = NV_SUBDEV(GPIO, 0x50),
	.base.ofuncs = &(struct nouveau_ofuncs) {
		.ctor = nv50_gpio_ctor,
		.dtor = nv50_gpio_dtor,
		.init = nv50_gpio_init,
		.fini = nv50_gpio_fini,
		.dtor = _nouveau_gpio_dtor,
		.init = _nouveau_gpio_init,
		.fini = _nouveau_gpio_fini,
	},
	.lines = 16,
	.intr_stat = nv50_gpio_intr_stat,
+3 −3
Original line number Diff line number Diff line
@@ -61,9 +61,9 @@ nv92_gpio_oclass = &(struct nouveau_gpio_impl) {
	.base.handle = NV_SUBDEV(GPIO, 0x92),
	.base.ofuncs = &(struct nouveau_ofuncs) {
		.ctor = nv50_gpio_ctor,
		.dtor = nv50_gpio_dtor,
		.init = nv50_gpio_init,
		.fini = nv50_gpio_fini,
		.dtor = _nouveau_gpio_dtor,
		.init = _nouveau_gpio_init,
		.fini = _nouveau_gpio_fini,
	},
	.lines = 32,
	.intr_stat = nv92_gpio_intr_stat,
+3 −3
Original line number Diff line number Diff line
@@ -96,9 +96,9 @@ nvd0_gpio_oclass = &(struct nouveau_gpio_impl) {
	.base.handle = NV_SUBDEV(GPIO, 0xd0),
	.base.ofuncs = &(struct nouveau_ofuncs) {
		.ctor = nvd0_gpio_ctor,
		.dtor = nv50_gpio_dtor,
		.init = nv50_gpio_init,
		.fini = nv50_gpio_fini,
		.dtor = _nouveau_gpio_dtor,
		.init = _nouveau_gpio_init,
		.fini = _nouveau_gpio_fini,
	},
	.lines = 32,
	.intr_stat = nv92_gpio_intr_stat,
Loading