18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci** hppb.c:
48c2ecf20Sopenharmony_ci**      HP-PB bus driver for the NOVA and K-Class systems.
58c2ecf20Sopenharmony_ci**
68c2ecf20Sopenharmony_ci**      (c) Copyright 2002 Ryan Bradetich
78c2ecf20Sopenharmony_ci**      (c) Copyright 2002 Hewlett-Packard Company
88c2ecf20Sopenharmony_ci**
98c2ecf20Sopenharmony_ci**
108c2ecf20Sopenharmony_ci*/
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/types.h>
138c2ecf20Sopenharmony_ci#include <linux/init.h>
148c2ecf20Sopenharmony_ci#include <linux/mm.h>
158c2ecf20Sopenharmony_ci#include <linux/slab.h>
168c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
178c2ecf20Sopenharmony_ci#include <linux/ioport.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#include <asm/io.h>
208c2ecf20Sopenharmony_ci#include <asm/hardware.h>
218c2ecf20Sopenharmony_ci#include <asm/parisc-device.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#include "iommu.h"
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistruct hppb_card {
268c2ecf20Sopenharmony_ci	unsigned long hpa;
278c2ecf20Sopenharmony_ci	struct resource mmio_region;
288c2ecf20Sopenharmony_ci	struct hppb_card *next;
298c2ecf20Sopenharmony_ci};
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic struct hppb_card hppb_card_head = {
328c2ecf20Sopenharmony_ci	.hpa = 0,
338c2ecf20Sopenharmony_ci	.next = NULL,
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#define IO_IO_LOW  offsetof(struct bc_module, io_io_low)
378c2ecf20Sopenharmony_ci#define IO_IO_HIGH offsetof(struct bc_module, io_io_high)
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci/**
408c2ecf20Sopenharmony_ci * hppb_probe - Determine if the hppb driver should claim this device.
418c2ecf20Sopenharmony_ci * @dev: The device which has been found
428c2ecf20Sopenharmony_ci *
438c2ecf20Sopenharmony_ci * Determine if hppb driver should claim this chip (return 0) or not
448c2ecf20Sopenharmony_ci * (return 1). If so, initialize the chip and tell other partners in crime
458c2ecf20Sopenharmony_ci * they have work to do.
468c2ecf20Sopenharmony_ci */
478c2ecf20Sopenharmony_cistatic int __init hppb_probe(struct parisc_device *dev)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	int status;
508c2ecf20Sopenharmony_ci	struct hppb_card *card = &hppb_card_head;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	while(card->next) {
538c2ecf20Sopenharmony_ci		card = card->next;
548c2ecf20Sopenharmony_ci	}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	if(card->hpa) {
578c2ecf20Sopenharmony_ci		card->next = kzalloc(sizeof(struct hppb_card), GFP_KERNEL);
588c2ecf20Sopenharmony_ci		if(!card->next) {
598c2ecf20Sopenharmony_ci			printk(KERN_ERR "HP-PB: Unable to allocate memory.\n");
608c2ecf20Sopenharmony_ci			return 1;
618c2ecf20Sopenharmony_ci		}
628c2ecf20Sopenharmony_ci		card = card->next;
638c2ecf20Sopenharmony_ci	}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	card->hpa = dev->hpa.start;
668c2ecf20Sopenharmony_ci	card->mmio_region.name = "HP-PB Bus";
678c2ecf20Sopenharmony_ci	card->mmio_region.flags = IORESOURCE_MEM;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	card->mmio_region.start = gsc_readl(dev->hpa.start + IO_IO_LOW);
708c2ecf20Sopenharmony_ci	card->mmio_region.end = gsc_readl(dev->hpa.start + IO_IO_HIGH) - 1;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	status = ccio_request_resource(dev, &card->mmio_region);
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	pr_info("Found GeckoBoa at %pap, bus space %pR,%s claimed.\n",
758c2ecf20Sopenharmony_ci			&dev->hpa.start,
768c2ecf20Sopenharmony_ci			&card->mmio_region,
778c2ecf20Sopenharmony_ci			(status < 0) ? " not":"" );
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci        return 0;
808c2ecf20Sopenharmony_ci}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_cistatic const struct parisc_device_id hppb_tbl[] __initconst = {
838c2ecf20Sopenharmony_ci        { HPHW_BCPORT, HVERSION_REV_ANY_ID, 0x500, 0xc }, /* E25 and K */
848c2ecf20Sopenharmony_ci        { HPHW_BCPORT, 0x0, 0x501, 0xc }, /* E35 */
858c2ecf20Sopenharmony_ci        { HPHW_BCPORT, 0x0, 0x502, 0xc }, /* E45 */
868c2ecf20Sopenharmony_ci        { HPHW_BCPORT, 0x0, 0x503, 0xc }, /* E55 */
878c2ecf20Sopenharmony_ci        { 0, }
888c2ecf20Sopenharmony_ci};
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_cistatic struct parisc_driver hppb_driver __refdata = {
918c2ecf20Sopenharmony_ci        .name =         "gecko_boa",
928c2ecf20Sopenharmony_ci        .id_table =     hppb_tbl,
938c2ecf20Sopenharmony_ci	.probe =        hppb_probe,
948c2ecf20Sopenharmony_ci};
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci/**
978c2ecf20Sopenharmony_ci * hppb_init - HP-PB bus initialization procedure.
988c2ecf20Sopenharmony_ci *
998c2ecf20Sopenharmony_ci * Register this driver.
1008c2ecf20Sopenharmony_ci */
1018c2ecf20Sopenharmony_civoid __init hppb_init(void)
1028c2ecf20Sopenharmony_ci{
1038c2ecf20Sopenharmony_ci        register_parisc_driver(&hppb_driver);
1048c2ecf20Sopenharmony_ci}
105